Project Stage 2: Custom Implementation
For this stage of the project I had to implement my own custom GCC pass to iterate through the code in the program that was being compiled. Below is my code.
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
#include "tree-pass.h"
#include "context.h"
#include "function.h"
#include "basic-block.h"
#include "cfg.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-pretty-print.h"
namespace {
const pass_data pass_data_ctyler = {
GIMPLE_PASS, // Type
"ctyler", // Name
OPTGROUP_NONE, // Option group
TV_NONE, // TV identifier
PROP_cfg, // Properties required
0, // Properties provided
0, // Properties destroyed
0, // To-do flags start
0 // To-do flags finish
};
class pass_ctyler : public gimple_opt_pass {
public:
pass_ctyler(gcc::context *ctxt) : gimple_opt_pass(pass_data_ctyler, ctxt) {}
// Always execute the pass
bool gate(function *) override { return true; }
// Main logic for the pass
unsigned int execute(function *fun) override {
basic_block bb;
// Iterate over all basic blocks
FOR_EACH_BB_FN(bb, fun) {
gimple_stmt_iterator gsi;
// Iterate over all statements in the basic block
for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
gimple *stmt = gsi_stmt(gsi);
if (dump_file) {
print_gimple_stmt(dump_file, stmt, 0, TDF_SLIM);
}
}
}
// Emit a diagnostic message
if (dump_file) {
fprintf(dump_file, "PRUNE: %s\n", IDENTIFIER_POINTER(DECL_NAME(fun->decl)));
}
return 0;
}
};
} // End anonymous namespace
// Factory function to create the pass
gimple_opt_pass *make_pass_ctyler(gcc::context *ctxt) {
return new pass_ctyler(ctxt);
}
I modified the sample pass that was provided to us by our professor and tried to implement my own code to iterate through the code, log gimple statements, and output a diagnostic prune: function_name message.
My code in comparison to the sample one is provides more simple information than the professors and simply tracks functions and their GIMPLE statements.
const pass_data pass_data_ctyler = {
GIMPLE_PASS, // Type
"ctyler", // Name
OPTGROUP_NONE, // Option group
TV_NONE, // TV identifier
PROP_cfg, // Properties required
0, // Properties provided
0, // Properties destroyed
0, // To-do flags start
0 // To-do flags finish
};
The initial part of my code is similar and just provides metadata for GCC about the pass itself. The main changes I made to the program were within the main logic of the code.
unsigned int execute(function *fun) override {
basic_block bb;
// Iterate over all basic blocks
FOR_EACH_BB_FN(bb, fun) {
gimple_stmt_iterator gsi;
// Iterate over all statements in the basic block
for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
gimple *stmt = gsi_stmt(gsi);
if (dump_file) {
print_gimple_stmt(dump_file, stmt, 0, TDF_SLIM);
}
}
}
// Emit a diagnostic message
if (dump_file) {
fprintf(dump_file, "PRUNE: %s\n", IDENTIFIER_POINTER(DECL_NAME(fun->decl)));
}
return 0;
}
Comments
Post a Comment