Project Stage 2 - (Implementation)
In this blog post, I'll delve into the detailed implementation of a new pass named "prune_clones" in GCC. This pass aims to traverse the call graph and prune duplicate clones, enhancing optimization capabilities within the compiler.
Introduction
In previous discussions, I outlined a plan to integrate a new pass into GCC for optimizing clone functions. Here, I will focus on the concrete implementation details, showcasing how this pass is structured and integrated into GCC's build process.
1. Create the New Pass File:
First, create the new source file 'prune-clones.cc'
in the GCC source directory.
[sshin36@aarch64-001 gcc]$ touch prune-clones.cc
2. Write the Code for the New Pass:
Define the Pass Data Structure:
create the pass data structure to define the properties of new pass
#include "cgraph.h"
#include "tree-pass.h"
// Define the pass data structure
const pass_data pass_data_prune_clones = {
GIMPLE_PASS, // type
"prune_clones", // name
OPTGROUP_NONE, // optinfo_flags
TV_NONE, // tv_id
0, // properties_required
0, // properties_provided
0, // properties_destroyed
0, // todo_flags_start
0 // todo_flags_finish
};
Define the Pass Class:
define the pass class that inherits from 'gimple_opt_pass'.
// Define the pass class
class pass_prune_clones : public gimple_opt_pass {
public:
pass_prune_clones(gcc::context *ctxt)
: gimple_opt_pass(pass_data_prune_clones, ctxt) {}
unsigned int execute(function *fun) final override;
};
Implement the Execute Function
Implement the execute
function that traverses the call graph and prunes duplicate clones.
// Execute function for the pass
unsigned int pass_prune_clones::execute(function *fun) {
// Walk each function in the call graph
FOR_EACH_FUNCTION(node) {
// If node points to SIMD clones
if (node->simd_clones) {
prune_clones(node);
}
}
return 0;
}
Implement the Pruning Function
define the 'prune_clones' function to handle the actual pruning logic.
// Function to prune duplicate clones
unsigned int prune_clones(cgraph_node *node) {
cgraph_function_version_info *default_fvi = node->function_version();
cgraph_function_version_info *curr_fvi = node->function_version();
while (curr_fvi->next) {
// Get the next clone
curr_fvi = curr_fvi->next;
// Compare to the default node
// Prune if duplicate
}
return 0;
}
Create a Function to Instantiate the Pass
create a helper function to instantiate the pass.
// Function to create a new instance of the gimple_opt_pass
gimple_opt_pass *make_pass_prune_clones(gcc::context *ctxt) {
return new pass_prune_clones(ctxt);
}
NEXT_PASS (pass_data_prund_clones);
5. Update 'gcc/gcc.cc':
#include "prune-clones.h"
int
driver::main (int argc, char **argv)
{
bool early_exit;
g->add_pass(make_pass_prune_clones(ctxt));
set_progname (argv[0]);
expand_at_files (&argc, &argv);
댓글
댓글 쓰기