Project Stage 3 - Tide & Wrap

 

Intro

This post will wrap up the project for SPO600 course. As a reminder; the goal of this project was to modify GCC Compiler to check if a cloned function can be pruned or not. However, I couldn't achieve the goal. Instead, I made a few small progresses. In this post, I will explain and wrap up the progresses that I made so far.

Progress

I made a few more changes from Stage 2. Actually this version is made by combining different versions of the pass implementations that I have made during this project. So it's not a huge progress:

unsigned int pass_ctyler::execute(function *)
{
    struct cgraph_node *node;
    int func_cnt = 0;
    int *stmt_counts = (int *)xmalloc(30 * sizeof(int));

    FOR_EACH_FUNCTION(node)
    {
	int stmt_cnt = 0;
        if (dump_file)
        {
	    if (node)
            {
            	fprintf(dump_file, "Function Name === %s\n", node->name());
            	function *fn = node->get_fun();
            	if (fn)
            	{
                	basic_block bb;
                	FOR_EACH_BB_FN(bb, fn)
			{
				for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
          			{
            				gimple *g = gsi_stmt (gsi);
            				stmt_cnt++;
                			print_gimple_stmt (dump_file, g, 0, TDF_VOPS|TDF_MEMSYMS);
              			}
			}

		stmt_counts[func_cnt]= stmt_cnt;
		fprintf(dump_file, "Statement Count: %d \n", stmt_cnt);
		func_cnt++;
    		}
	    }
	}
    }

    if (dump_file)
    {
        fprintf(dump_file, "\n\n#### End ctyler diagnostics, start regular dump of current gimple ####\n\n\n");
    	for (int i = 0; i < func_cnt; i++)
        {
            fprintf(dump_file, "Function %d: %d statements\n", i + 1, stmt_counts[i]);
        }
    }

    free(stmt_counts);

    return 0;
}

This is the final version of my gcc compiler. The entire gcc compiler is available Here

The current version of My gcc compiler is able to:

    1. Print function name

    2. print gimple statements.

    2. Print the number of gimple statements for each function

    3. Store the number of gimple statements for each function in an array

    4. Ready to compare the number of statements to check the necessity of pruning


A part of my test result is as follows:

;; Function scale_samples (scale_samples.default, funcdef_no=7, decl_uid=3871, cgraph_uid=8, symbol_order=7)

Function Name === __builtin_cpu_supports
Function Name === __builtin_cpu_init
Function Name === scale_samples.resolver
# .MEM_2 = VDEF <.MEM_1(D)>
__builtin_cpu_init ();
_3 = __builtin_cpu_supports (&"x86-64-v3"[0]);
if (_3 > 0)
_5 = (void *) scale_samples.arch_x86_64_v3;
# VUSE <.MEM_2>
return _5;
_4 = (void *) scale_samples;
# VUSE <.MEM_2>
return _4;
Statement Count: 7
Function Name === scale_samples
Function Name === scale_samples.arch_x86_64_v3
x_1 = 0;
_3 = (long unsigned int) x_2;
_4 = _3 * 2;
_6 = in_5(D) + _4;
# VUSE <.MEM_22>
_7 = *_6;
_8 = (int) _7;
_10 = volume_9(D) * 32767;
_11 = _10 / 100;
_12 = _11 << 1;
_13 = _8 * _12;
_14 = _13 >> 16;
_15 = (long unsigned int) x_2;
_16 = _15 * 2;
_18 = out_17(D) + _16;
_19 = (short int) _14;
# .MEM_24 = VDEF <.MEM_22>
*_18 = _19;
x_20 = x_2 + 1;
if (x_2 < cnt_21(D))
# VUSE <.MEM_22>
return;
Statement Count: 19
Function Name === printf
Function Name === vol_createsample
Function Name === calloc
Function Name === main
ttl_1 = 0;
# .MEM_3 = VDEF <.MEM_2(D)>
in_4 = calloc (50000000, 2);
# .MEM_5 = VDEF <.MEM_3>
out_6 = calloc (50000000, 2);
# .MEM_7 = VDEF <.MEM_5>
vol_createsample (in_4, 50000000);
# .MEM_8 = VDEF <.MEM_7>
scale_samples (in_4, out_6, 50000000, 50);
# .MEM_9 = VDEF <.MEM_8>
ttl_10 = sum_sample (out_6, 50000000);
# .MEM_11 = VDEF <.MEM_9>
printf ("Result: %d\n", ttl_10);
_12 = 0;
<L0>:
# VUSE <.MEM_11>
return _12;
Statement Count: 10
Function Name === scale_samples
x_17 = 0;
_1 = (long unsigned int) x_15;
_2 = _1 * 2;
_3 = in_20(D) + _2;
# VUSE <.MEM_16>
_4 = *_3;
_5 = (int) _4;
_6 = volume_21(D) * 32767;
_7 = _6 / 100;
_8 = _7 << 1;
_9 = _5 * _8;
_10 = _9 >> 16;
_11 = (long unsigned int) x_15;
_12 = _11 * 2;
_13 = out_22(D) + _12;
_14 = (short int) _10;
# .MEM_23 = VDEF <.MEM_16>
*_13 = _14;
x_24 = x_15 + 1;
if (x_15 < cnt_19(D))
# VUSE <.MEM_16>
return;
Statement Count: 19
Function Name === sum_sample


#### End ctyler diagnostics, start regular dump of current gimple ####

Function 1: 7 statements
Function 2: 19 statements
Function 3: 10 statements
Function 4: 19 statements

The whole test output for non-prune-test-code is available here.

The whole test output for prune-test-code is available here.


Challenges

Based on the result, It looks like the following code is executed many times

during the tree-ctyler pass.

unsigned int pass_ctyler::execute(function *)

If I am being honest, I don't know why that happens.

This result makes me so confused and makes the pruning test much more difficult.

Moreover, this is not the only problem that I had during this project. GCC compiler

Codebase is huge. It's really difficult to understand the structure of node,

and basic block, and function. Even just printing some information of

those structures was literally all I could do.


Further Improvement

As I mentioned above, currently I have little understanding of GCC Compiler.

Therefore, to make a meaningful progress, I need to spend a lot of effort and

time on studying and reading the GCC Compiler. Once I understand better

about the structures of node, function, and passes, then I think I need to

take a look at how I could compare the cloned functions.


Reflection


This course was by far the most challenging course I have ever taken at Seneca.

And I really feel bad about making little progress for this project.

However, I learned a lot about GCC Compiler such as How to install, build,

compile, and add passes.

Before this course, I didn't even imagine that I could ever make some chnages

in GCC compiler. However, I did. Even though my progress is really trivial.

I think the fact that I made a change in GCC Compiler is important.








Comments

popular posts in this blog

Project Stage 2 - part 2 : Clone-Pruning Analysis Pass

Project Stage 2 part 4 - Testing clone-test-core.c file with Modified GCC file and making further modification

Project Stage 2 part 3 - Compile a program with revised GCC