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 chnagesin 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
Post a Comment