Project Stage 1: Create a Basic GCC Pass
After performed Lab4, at this stage we create a pass for the current development version of the GCC compiler which:
Step 3: Include New Pass in passes.def
The passes.def file contains all the macros needed to manage GCC passes. We now need to insert our hxu_pass in this file so that GCC knows when to invoke it during compilation.
Since early passes handle parsing and gimplification, and later passes handle final transformations and code generation, we will place our hxu_pass late in the optimization pipeline, so we can analyze code after most optimizations are done.
Once I added NEXT_PASS to passes.def,
I also need to declare the make_hxu_pass function in tree-pass.h.
Step 5: Update the Build System (Makefile.in)
To make sure hxu_pass.cc gets compiled, Ineed to add it to Makefile.in.
nano Makefile.in
then search OBJS = \ AND add my pass:
Step 6: Rebuild GCC
ran following commends:
cd ~/gcc-build-001
rm Makefile
~/SomeLocalDir/configure --prefix=$HOME/gcc-test-001
time make -j 20 |& tee rebuild.log
Execute test command:
then view the generated dump file:
Result on X86-001:
Although the overall goal of this project is clear, it was difficult for me to fully understand the specific meaning and process at first. Especially as a beginner in GCC internals, it took time to grasp how GIMPLE passes work and how to properly register them in the compiler pipeline. In addition, troubleshooting errors during the integration process was quite challenging, since GCC's build system and pass registration are complex. This project stage1 helps understand and extend GCC’s compilation pipeline by adding a custom analysis phase, which can be a foundation for more advanced optimizations.
- Iterates through the code being compiled;
- Prints the name of every function being compiled;
- Prints a count of the number of basic blocks in each function; and
- Prints a count of the number of gimple statements in each function.
I already have ~/SomeLocalDir: GCC source code directory
~/gcc-build-001: GCC build directory (where I ran configure).
~/gcc-test-001:Installation directory
Create my-pass.cc file: nano hxu_pass.cc~/gcc-build-001: GCC build directory (where I ran configure).
~/gcc-test-001:Installation directory
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
#include "tree-pass.h"
#include "cgraph.h"
#include "function.h"
#include "basic-block.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "cfg.h"
namespace {
const pass_data hxu_pass_data = {
GIMPLE_PASS, // Type of pass
"hxu_pass", // Name of pass
OPTGROUP_NONE, // No optimization group
TV_NONE, // No timevar
PROP_cfg, // Properties required
0, // Properties provided
0, // Properties destroyed
0, // todo_flags_start
0 // todo_flags_finish
};
// Pass class definition
class hxu_pass : public gimple_opt_pass {
public:
hxu_pass(gcc::context *ctxt) : gimple_opt_pass(hxu_pass_data, ctxt) {}
unsigned int execute(function *fun) override {
int bb_cnt = 0, gimple_stmt_cnt = 0;
basic_block bb;
// Iterate over basic blocks
FOR_ALL_BB_FN(bb, fun) {
bb_cnt++;
// Iterate over GIMPLE statements in each basic block
for (gimple_stmt_iterator gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
gimple_stmt_cnt++;
}
}
// Output to dump file (if enabled)
if (dump_file) {
fprintf(dump_file, "=== Function '%s' ===\n", function_name(fun));
fprintf(dump_file, " Number of Basic Blocks: %d\n", bb_cnt);
fprintf(dump_file, " Number of GIMPLE statements: %d\n\n", gimple_stmt_cnt);
}
return 0;
}
};
} // end anonymous namespace
// Factory method to create the pass
gimple_opt_pass *make_pass_hxu(gcc::context *ctxt) {
return new hxu_pass(ctxt);
}
The passes.def file contains all the macros needed to manage GCC passes. We now need to insert our hxu_pass in this file so that GCC knows when to invoke it during compilation.
Since early passes handle parsing and gimplification, and later passes handle final transformations and code generation, we will place our hxu_pass late in the optimization pipeline, so we can analyze code after most optimizations are done.
Once I added NEXT_PASS to passes.def,
I also need to declare the make_hxu_pass function in tree-pass.h.
nano Makefile.in
then search OBJS = \ AND add my pass:
cd ~/gcc-build-001
rm Makefile
~/SomeLocalDir/configure --prefix=$HOME/gcc-test-001
time make -j 20 |& tee rebuild.log
Step 7: Testing Pass
./xgcc -B./ -g -O0 -fno-builtin -fdump-tree-hxu_pass -o hello hello.c
Result on X86-001:
Although the overall goal of this project is clear, it was difficult for me to fully understand the specific meaning and process at first. Especially as a beginner in GCC internals, it took time to grasp how GIMPLE passes work and how to properly register them in the compiler pipeline. In addition, troubleshooting errors during the integration process was quite challenging, since GCC's build system and pass registration are complex. This project stage1 helps understand and extend GCC’s compilation pipeline by adding a custom analysis phase, which can be a foundation for more advanced optimizations.
Comments
Post a Comment