Week 7 - GCC Passes & Project Stage 1

Welcome everyone! As the weeks go by, the material I will cover may be more advanced or difficult to grasp. But we are in this together and I hope that my article explains it effectively. In this article, I will briefly discuss GCC passes and also dive right into the Project Stage 1!
What are GCC Passes?
Think of GCC passes as stages that transform your source code into machine code. We know that the gcc compiler enables our code in C or C++ to be transformed into machine code so that it may be understood and executed. So while this process contains several steps, GCC passes are key as these are the driving forces in transforming our C/C++ code into machine code.
To learn more about these passes, please open your gcc directory and go to the gcc subdirectory. In here, you will see many files that perform GCC passes. The different types you’ll see include:
Tree
IPA
LTO
RTL
What if you wanted to create your own GCC pass? (We will be doing this for the project). There are six main steps.
Creating a GCC Pass
Create your pass file
Edit the passes.def file
Add the pass to tree-pass.h
Edit the Makefile.in
Rebuild the Makefile
Test out the gcc pass on a function
I will first start off by showing my code, explaining it, and then going through each step. So lets get started with the first step, creating the pass file. I created my pass file as follows:
Step 1. Creating .cc pass file
Navigate to the gcc subdirectory →
cd ~/git/gcc/gcc
Create a new file, I named mine hamza_gcc_pass.cc →
touch tree-hteli1.cc
I used vi to edit it →
vi tree-hteli1.cc
And finally I pasted my pass in here as follows:
/* This pass was creatd by Hamza Teli with the help of
Professor Chris Tyler's SPO600 wiki and lecture.
This pass accomplishes the following:
*/
// These headers were taken from Professor Chris Tyler's Week 7 Lecture
// These headers were taken from Professor Chris Tyler's Week 7 Lecture
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "ssa.h"
#include "tree-pretty-print.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "internal-fn.h"
#include "gimple-pretty-print.h"
#include "cgraph.h"
// Added headers
#include "gimple-ssa.h"
#include "attribs.h"
#include "pretty-print.h"
#include "tree-inline.h"
#include "intl.h"
#include "function.h"
#include "basic-block.h"
// Namespace <--- This section I learned from SPO600 Week 7 - Class 1 Lecture from Professor Chris Tyler
namespace{
const pass_data pass_data_hteli1 = {
GIMPLE_PASS, /* type */
"hteli1", /* name of my pass [We will use this inside passes.def as pass_hteli1_pass]*/
OPTGROUP_NONE, /* optinfo_ flags */
TV_NONE, /* tv_id */
PROP_cfg, /* specify that we need properties */
0, /* the properties provided */
0, /* the properties destroyed */
0, /* todo_flags_start */
0, /* todo_flags_finish */
};
/*
Please refer to the instructions below from Professor CHris Tyler that helped me build the class:
Pass Code
Each pass provides a C++ source file which provides:
- A pass_data structure which defines the pass details (defined in tree-pass.h);
- A class which defines a gimple_opt_pass and includes the public methods gate and execute.
- The gate method controls whether the pass is active. It can consider multiple factors, including command-line arguments, source language, and target. This method returns a boolean.
- The execute method executes the pass. It accepts a pointer to a function object and will be called once for each function in the unit being compiled (which is not always what you want!).
- A method in the anon namespace named make_pass_name which returns a pointer to the gimple_opt_pass described above.
*/
// This is where you identify the class
class pass_hteli1 : public gimple_opt_pass {
public:
// Constructor
pass_hteli1(gcc::context *ctxt) : gimple_opt_pass(pass_data_hteli1, ctxt) {
}
// The gate function
bool gate(function *) final override {
// return
return true;
}
// The execute function: this is where the magic happens
unsigned int execute (function *func) override {
// Declarations
// Count the number of basic blocks
unsigned int number_of_basic_blocks = 0;
// Count the number of Gimple statements
unsigned int number_of_gimple_statements = 0;
// Instantiate function name
/*
Inside function.cc, there's a function_name method that returns
the name of a function. Check out line 6454:
https://github.com/gcc-mirror/gcc/blob/master/gcc/function.cc
*/
const char* functionName = function_name(func);
// Print the name of each function being compiled
if (dump_file) {
fprintf(dump_file, "Function: %s\n", functionName);
}
// Now we use the macro FOR_EACH_FUNCTION to get the number of basic blocks
// and print the number of gimple statements in each function
basic_block BB;
FOR_EACH_BB_FN(BB, func) {
// Increment
number_of_basic_blocks++;
// Now for each basic block, iterate using the gimple iterator in the wiki
// Credit: http://spo600.cdot.systems/doku.php?id=spo600:creating_a_gcc_pass
for (gimple_stmt_iterator gsi = gsi_start_bb (BB); !gsi_end_p (gsi); gsi_next(&gsi)) {
number_of_gimple_statements++;
}
}
// Now we can print the basic blocks
if (dump_file) {
fprintf(dump_file, "---- Function: %s | Basic Blocks: %u, | Gimple Statements: %u\n", functionName, number_of_basic_blocks, number_of_gimple_statements);
}
// Return value
return 0;
}
};
}
// This is used inside the tree-pass.h file
gimple_opt_pass* make_pass_hteli1(gcc::context *ctxt) {
return new pass_hteli1(ctxt);
}
- To save → Press
ESC
and type:wq
and pressenter
NOTE: I have also uploaded my code to a git repository which can be accessed here: https://github.com/Hamza-Teli/spo600-gcc-project/blob/main/hamza_gcc_pass.cc
Please feel free to look at the revisions I made to see how I came to the final code. It took me quite a bit of trial and error (13 commits). But again thats how you learn best.
Breaking the code down
When I first seen this code, I too got scared. There’s a lot going on but I will explain it how I understand and hopefully you can learn as well.
First thing first, there is a section for the header whereby we have to include the necessary ones in order for our pass to execute. This is actually where I had initially run into problems.
const pass_data structure: Inside here we’re just defining the type of pass it is, the name, and other properties. This is needed for the gcc to add our pass in and identify it.
class declaration: Inside here we have a gate function and execute:
gate function: Just specifies if the pass should run on every function. Because I returned true, this means it will.
execute function: This function does a few things.
Gets the functions name using func_name
Uses the FOR_EACH_BB_FN macro to iterate over the basic blocks
Inside each block we increment the total GIMPLE statements
Print the function name, total basic blocks, and gimple statements
Step 2. Edit the passes.def file
The passes.def file contains a list of passes, all we have to do here is add our pass. To do this, follow the steps below:
Navigate to the source directory →
cd ~/git/gcc/gcc
Open passes.def →
vi passes.def
Add the following near the end of the file:
NEXT_PASS (pass_hteli1);
Heres an image:
To save → Press
ESC
and type:wq
and pressenter
Step 3. Add the pass to tree-pass.h
Now we add the pass to tree-pass.h, this step is simple as well. Please do the following:
Navigate to the source directory →
cd ~/git/gcc/gcc
Open tree-pass.h →
vi tree-pass.h
Add the following near the end of the file:
extern gimple_opt_pass *make_pass_hteli1 (gcc::context *ctxt);
To save → Press
ESC
and type:wq
and pressenter
Step 4. Edit the Makefile.in
Navigate to the gcc source directory →
cd ~/git/gcc/gcc
Open Makefile.in →
vi Makefile.in
Locate the
OBJS =
section → Should look like this:Add the following inside the section →
tree-hteli1.o \
To save → Press
ESC
and type:wq
and pressenter
Step 5. Rebuild the Makefile
Initially, I rebuilt the makefile however, it did not work. Therefore, I thought about the previous lab I completed (Lab 4) and started the build from scratch. This is what I realized. Firstly, to setup the pass we strictly use gcc source directory. Therefore, all I have to do is create my pass file there, setup the tree-pas.h, passes.def, and Makefile.in. Once thats done, I delete the old build folder and test folder as well. I perform the exact steps I did in Lab 4 and run make install at the end. Here’s a quick overview:
Delete any existing builds along with the test folder using rm → rm ~/gcc-build-001
Create a new gcc-build directory →
mkdir ~/gcc-build-001
Go into this directory →
cd ~/gcc-build-001
Set the configure →
~/git/gcc/configure —prefix=$HOME/gcc-test-001
Create a screen session →
screen -S project1
Execute make command →
time make -j$(nproc) |& tee rebuild_log.log
Execute make install →
make install
On the x86 machine, this is the output I received after running the make -j command:
---- Function: process_bb | Basic Blocks: 306, | Gimple Statements: 763
Function: find_func_aliases
---- Function: find_func_aliases | Basic Blocks: 532, | Gimple Statements: 1477
Function: maybe_optimize_range_tests
---- Function: maybe_optimize_range_tests | Basic Blocks: 392, | Gimple Statements: 1040
Function: hash_table<shared_bitmap_hasher>::expand
---- Function: hash_table<shared_bitmap_hasher>::expand | Basic Blocks: 37, | Gimple Statements: 110
Function: do_rpo_vn_1
---- Function: do_rpo_vn_1 | Basic Blocks: 365, | Gimple Statements: 1189
Function: hash_table<shared_bitmap_hasher>::find_slot_with_hash
---- Function: hash_table<shared_bitmap_hasher>::find_slot_with_hash | Basic Blocks: 49, | Gimple Statements: 141
Function: hash_table<hash_map<variable_info*, pt_solution*>::hash_entry, false, xcallocator>::expand
---- Function: hash_table<hash_map<variable_info*, pt_solution*>::hash_entry, false, xcallocator>::expand | Basic Blocks: 37, | Gimple Statements: 113
Function: find_what_var_points_to.isra
---- Function: find_what_var_points_to.isra | Basic Blocks: 167, | Gimple Statements: 476
Function: find_what_p_points_to
---- Function: find_what_p_points_to | Basic Blocks: 44, | Gimple Statements: 106
Function: run_rpo_vn
---- Function: run_rpo_vn | Basic Blocks: 103, | Gimple Statements: 277
Function: do_rpo_vn
---- Function: do_rpo_vn | Basic Blocks: 4, | Gimple Statements: 12
Function: {anonymous}::pass_fre::execute
---- Function: {anonymous}::pass_fre::execute | Basic Blocks: 9, | Gimple Statements: 20
Function: compute_may_aliases
---- Function: compute_may_aliases | Basic Blocks: 190, | Gimple Statements: 590
Function: {anonymous}::pass_reassoc::execute
---- Function: {anonymous}::pass_reassoc::execute | Basic Blocks: 560, | Gimple Statements: 1590
Function: vn_reference_lookup_3
---- Function: vn_reference_lookup_3 | Basic Blocks: 654, | Gimple Statements: 1905
Function: _GLOBAL__sub_I__Z16dump_range_entryP8_IO_FILEP11range_entryb
---- Function: _GLOBAL__sub_I__Z16dump_range_entryP8_IO_FILEP11range_entryb | Basic Blocks: 1, | Gimple Statements: 20
Function: {anonymous}::pass_ipa_pta::execute
---- Function: {anonymous}::pass_ipa_pta::execute | Basic Blocks: 436, | Gimple Statements: 1245
Function: _GLOBAL__sub_I_final_solutions_obstack
---- Function: _GLOBAL__sub_I_final_solutions_obstack | Basic Blocks: 1, | Gimple Statements: 29
.........
dep.o .libs/libubsan.lax/libsanitizer_common.a/sanitizer_symbolizer_mac.o .libs/libubsan.lax/libsanitizer_common.a/sanitizer_symbolizer_markup.o .libs/libubsan.lax/libsanitizer_common.a/sanitizer_symbolizer_posix_libcdep.o .libs/libubsan.lax/libsanitizer_common.a/sanitizer_symbolizer_report.o .libs/libubsan.lax/libsanitizer_common.a/sanitizer_symbolizer_win.o .libs/libubsan.lax/libsanitizer_common.a/sanitizer_termination.o .libs/libubsan.lax/libsanitizer_common.a/sanitizer_thread_arg_retval.o .libs/libubsan.lax/libsanitizer_common.a/sanitizer_thread_history.o .libs/libubsan.lax/libsanitizer_common.a/sanitizer_thread_registry.o .libs/libubsan.lax/libsanitizer_common.a/sanitizer_tls_get_addr.o .libs/libubsan.lax/libsanitizer_common.a/sanitizer_unwind_linux_libcdep.o .libs/libubsan.lax/libsanitizer_common.a/sanitizer_unwind_win.o .libs/libubsan.lax/libsanitizer_common.a/sanitizer_win.o .libs/libubsan.lax/libsanitizer_common.a/sanitizer_win_interception.o .libs/libubsan.lax/libinterception.a/interception_linux.o .libs/libubsan.lax/libinterception.a/interception_mac.o .libs/libubsan.lax/libinterception.a/interception_type_test.o .libs/libubsan.lax/libinterception.a/interception_win.o .libs/libubsan.lax/libsanitizer_libbacktrace.a/atomic.o .libs/libubsan.lax/libsanitizer_libbacktrace.a/bridge.o .libs/libubsan.lax/libsanitizer_libbacktrace.a/cp-demangle.o .libs/libubsan.lax/libsanitizer_libbacktrace.a/dwarf.o .libs/libubsan.lax/libsanitizer_libbacktrace.a/elf.o .libs/libubsan.lax/libsanitizer_libbacktrace.a/fileline.o .libs/libubsan.lax/libsanitizer_libbacktrace.a/mmap.o .libs/libubsan.lax/libsanitizer_libbacktrace.a/mmapio.o .libs/libubsan.lax/libsanitizer_libbacktrace.a/posix.o .libs/libubsan.lax/libsanitizer_libbacktrace.a/sort.o .libs/libubsan.lax/libsanitizer_libbacktrace.a/state.o
libtool: link: ranlib --plugin /usr/libexec/gcc/x86_64-redhat-linux/14/liblto_plugin.so --plugin /home/hteli1/gcc-build-001/./gcc/liblto_plugin.so --plugin /home/hteli1/gcc-build-001/./gcc/liblto_plugin.so .libs/libubsan.a
libtool: link: rm -fr .libs/libubsan.lax
libtool: link: ( cd ".libs" && rm -f "libubsan.la" && ln -s "../libubsan.la" "libubsan.la" )
make[8]: Leaving directory '/home/hteli1/gcc-build-001/x86_64-pc-linux-gnu/32/libsanitizer/ubsan'
make[8]: Entering directory '/home/hteli1/gcc-build-001/x86_64-pc-linux-gnu/32/libsanitizer'
true "AR_FLAGS=rc" "CC_FOR_BUILD=gcc" "CFLAGS=-g -O2 -m32" "CXXFLAGS=-g -O2 -D_GNU_SOURCE -m32" "CFLAGS_FOR_BUILD=-g -O2" "CFLAGS_FOR_TARGET=-g -O2" "INSTALL=/usr/bin/install -c" "INSTALL_DATA=/usr/bin/install -c -m 644" "INSTALL_PROGRAM=/usr/bin/install -c" "INSTALL_SCRIPT=/usr/bin/install -c" "JC1FLAGS=" "LDFLAGS=-m32" "LIBCFLAGS=-g -O2 -m32" "LIBCFLAGS_FOR_TARGET=-g -O2" "MAKE=make" "MAKEINFO=/home/hteli1/git/gcc/missing makeinfo --split-size=5000000 " "PICFLAG=" "PICFLAG_FOR_TARGET=" "SHELL=/bin/sh" "RUNTESTFLAGS=" "exec_prefix=/home/hteli1/gcc-test-001" "infodir=/home/hteli1/gcc-test-001/share/info" "libdir=/home/hteli1/gcc-test-001/lib" "prefix=/home/hteli1/gcc-test-001" "includedir=/home/hteli1/gcc-test-001/include" "AR=ar --plugin /usr/libexec/gcc/x86_64-redhat-linux/14/liblto_plugin.so --plugin /home/hteli1/gcc-build-001/./gcc/liblto_plugin.so --plugin /home/hteli1/gcc-build-001/./gcc/liblto_plugin.so" "AS=/home/hteli1/gcc-build-001/./gcc/as" "LD=/home/hteli1/gcc-build-001/./gcc/collect-ld -m elf_x86_64 -m elf_i386" "LIBCFLAGS=-g -O2 -m32" "NM=/home/hteli1/gcc-build-001/./gcc/nm -B -B" "PICFLAG=" "RANLIB=ranlib --plugin /usr/libexec/gcc/x86_64-redhat-linux/14/liblto_plugin.so --plugin /home/hteli1/gcc-build-001/./gcc/liblto_plugin.so --plugin /home/hteli1/gcc-build-001/./gcc/liblto_plugin.so" "DESTDIR=" DO=all multi-do # make
make[8]: Leaving directory '/home/hteli1/gcc-build-001/x86_64-pc-linux-gnu/32/libsanitizer'
make[7]: Leaving directory '/home/hteli1/gcc-build-001/x86_64-pc-linux-gnu/32/libsanitizer'
make[6]: Leaving directory '/home/hteli1/gcc-build-001/x86_64-pc-linux-gnu/32/libsanitizer'
make[5]: Leaving directory '/home/hteli1/gcc-build-001/x86_64-pc-linux-gnu/libsanitizer'
make[4]: Leaving directory '/home/hteli1/gcc-build-001/x86_64-pc-linux-gnu/libsanitizer'
make[3]: Leaving directory '/home/hteli1/gcc-build-001/x86_64-pc-linux-gnu/libsanitizer'
make[2]: Leaving directory '/home/hteli1/gcc-build-001/x86_64-pc-linux-gnu/libsanitizer'
make[1]: Leaving directory '/home/hteli1/gcc-build-001'
Looking at the output, you can see that my pass is doing its job :) Although I don’t have the time which I am not sure why as I did run the entire command with time and re-directed the output to a file, this part did take about 30-40 minutes long. After that make install didn’t take that long.
Testing it out with a file
I decided to test my pass by using the spo600 directory from our Lab 4 experiment. However I did make a small change to the makefile to output the dump files. Here are the steps I took:
Navigate to the directory →
cd ~/spo600/examples/hello/c
Edit the Makefile →
vi Makefile
BINARIES=hello hello-static hello-opt hello2 hello3 CCFLAGS=-g -O0 -fno-builtin -fdump-tree-all all: ${BINARIES} hello: hello.c ~/gcc-test-001/bin/gcc ${CCFLAGS} -o hello hello.c # Statically-linked version hello-static: hello.c gcc ${CCFLAGS} -o hello-static -static hello.c # Optimized version hello-opt: hello.c gcc -O3 -g -o hello-opt hello.c hello2: hello2.c gcc ${CCFLAGS} -o hello2 hello2.c hello3: hello3.c gcc ${CCFLAGS} -o hello3 hello3.c clean: rm ${BINARIES} *.o || true
After making this change, I made sure to check which gcc my machine was using just to be safe:
NOTE: If it shows a different gcc, please execute the following command: PATH=”$HOME/gcc-test-001/bin:$PATH”
I then executed the make commands as follows:
make clean
make
This outputted the following files:
hteli1@x86-001:~/spo600/examples/hello/c$ ls
hello hello2.c.254t.cplxlower0 hello3.c.014t.eh hello3.c.269t.optimized hello.c.032t.local-fnsummary1 hello.c.368t.debug hello-static-hello.c.253t.veclower
hello2 hello2.c.255t.bitintlower0 hello3.c.016t.cfg hello3.c.269t.waccess3 hello.c.033t.einline hello-opt hello-static-hello.c.254t.cplxlower0
hello2.c hello2.c.257t.switchlower_O0 hello3.c.018t.ompexp hello3.c.270t.optimized hello.c.053t.profile_estimate hello.s hello-static-hello.c.255t.bitintlower0
hello2.c.006t.original hello2.c.265t.hteli1 hello3.c.022t.fixup_cfg1 hello3.c.365t.statistics hello.c.057t.release_ssa hello-static hello-static-hello.c.257t.switchlower_O0
hello2.c.007t.gimple hello2.c.265t.isel hello3.c.023t.ssa hello3.c.366t.earlydebug hello.c.058t.local-fnsummary2 hello-static-hello.c.006t.original hello-static-hello.c.265t.hteli1
hello2.c.010t.omplower hello2.c.266t.isel hello3.c.024t.walloca1 hello3.c.366t.statistics hello.c.099t.fixup_cfg3 hello-static-hello.c.007t.gimple hello-static-hello.c.265t.isel
hello2.c.011t.lower hello2.c.268t.waccess3 hello3.c.027t.waccess1 hello3.c.367t.debug hello.c.106t.adjust_alignment hello-static-hello.c.010t.omplower hello-static-hello.c.266t.isel
hello2.c.014t.eh hello2.c.269t.optimized hello3.c.031t.fixup_cfg2 hello3.c.367t.earlydebug hello.c.253t.veclower hello-static-hello.c.011t.lower hello-static-hello.c.268t.waccess3
hello2.c.016t.cfg hello2.c.269t.waccess3 hello3.c.032t.local-fnsummary1 hello3.c.368t.debug hello.c.254t.cplxlower0 hello-static-hello.c.014t.eh hello-static-hello.c.269t.optimized
hello2.c.018t.ompexp hello2.c.270t.optimized hello3.c.033t.einline hello3.s hello.c.255t.bitintlower0 hello-static-hello.c.016t.cfg hello-static-hello.c.269t.waccess3
hello2.c.022t.fixup_cfg1 hello2.c.365t.statistics hello3.c.053t.profile_estimate hello.c hello.c.257t.switchlower_O0 hello-static-hello.c.018t.ompexp hello-static-hello.c.270t.optimized
hello2.c.023t.ssa hello2.c.366t.earlydebug hello3.c.057t.release_ssa hello.c.006t.original hello.c.265t.hteli1 hello-static-hello.c.022t.fixup_cfg1 hello-static-hello.c.365t.statistics
hello2.c.024t.walloca1 hello2.c.366t.statistics hello3.c.058t.local-fnsummary2 hello.c.007t.gimple hello.c.265t.isel hello-static-hello.c.023t.ssa hello-static-hello.c.366t.earlydebug
hello2.c.027t.waccess1 hello2.c.367t.debug hello3.c.099t.fixup_cfg3 hello.c.010t.omplower hello.c.266t.isel hello-static-hello.c.024t.walloca1 hello-static-hello.c.366t.statistics
hello2.c.031t.fixup_cfg2 hello2.c.367t.earlydebug hello3.c.106t.adjust_alignment hello.c.011t.lower hello.c.268t.waccess3 hello-static-hello.c.027t.waccess1 hello-static-hello.c.367t.debug
hello2.c.032t.local-fnsummary1 hello2.c.368t.debug hello3.c.253t.veclower hello.c.014t.eh hello.c.269t.optimized hello-static-hello.c.031t.fixup_cfg2 hello-static-hello.c.367t.earlydebug
hello2.c.033t.einline hello2.s hello3.c.254t.cplxlower0 hello.c.016t.cfg hello.c.269t.waccess3 hello-static-hello.c.032t.local-fnsummary1 hello-static-hello.c.368t.debug
hello2.c.053t.profile_estimate hello3 hello3.c.255t.bitintlower0 hello.c.018t.ompexp hello.c.270t.optimized hello-static-hello.c.033t.einline Makefile
hello2.c.057t.release_ssa hello3.c hello3.c.257t.switchlower_O0 hello.c.022t.fixup_cfg1 hello.c.365t.statistics hello-static-hello.c.053t.profile_estimate
hello2.c.058t.local-fnsummary2 hello3.c.006t.original hello3.c.265t.hteli1 hello.c.023t.ssa hello.c.366t.earlydebug hello-static-hello.c.057t.release_ssa
hello2.c.099t.fixup_cfg3 hello3.c.007t.gimple hello3.c.265t.isel hello.c.024t.walloca1 hello.c.366t.statistics hello-static-hello.c.058t.local-fnsummary2
hello2.c.106t.adjust_alignment hello3.c.010t.omplower hello3.c.266t.isel hello.c.027t.waccess1 hello.c.367t.debug hello-static-hello.c.099t.fixup_cfg3
hello2.c.253t.veclower hello3.c.011t.lower hello3.c.268t.waccess3 hello.c.031t.fixup_cfg2 hello.c.367t.earlydebug hello-static-hello.c.106t.adjust_alignment
At this point there were too many dump files, so I changed my Makefile to only include my dump file: -fdump-tree-hteli1
:
BINARIES=hello hello-static hello-opt hello2 hello3
CCFLAGS=-g -O0 -fno-builtin -fdump-tree-hteli1
all: ${BINARIES}
hello: hello.c
~/gcc-test-001/bin/gcc ${CCFLAGS} -o hello hello.c
# Statically-linked version
hello-static: hello.c
gcc ${CCFLAGS} -o hello-static -static hello.c
# Optimized version
hello-opt: hello.c
gcc -O3 -g -o hello-opt hello.c
hello2: hello2.c
gcc ${CCFLAGS} -o hello2 hello2.c
hello3: hello3.c
gcc ${CCFLAGS} -o hello3 hello3.c
clean:
rm ${BINARIES} *.o || true
Output from dump file:
x86:
The output on the x86 is below:
hteli1@x86-001:~/spo600/examples/hello/c$ cat hello.c.265t.hteli1
;; Function main (main, funcdef_no=0, decl_uid=2335, cgraph_uid=1, symbol_order=0)
Function: main
---- Function: main | Basic Blocks: 2, | Gimple Statements: 4
int main ()
{
int D.2338;
int _3;
<bb 2> :
printf ("Hello World!\n");
_3 = 0;
<bb 3> :
<L0>:
return _3;
}
Here is an image:
AArch64:
The output for AArch64 is as follows:
[hteli1@aarch64-002 c]$ cat hello.c.265t.hteli1
;; Function main (main, funcdef_no=0, decl_uid=3927, cgraph_uid=1, symbol_order=0)
Function: main
---- Function: main | Basic Blocks: 2, | Gimple Statements: 4
int main ()
{
int D.3930;
int _3;
<bb 2> :
printf ("Hello World!\n");
_3 = 0;
<bb 3> :
<L0>:
return _3;
}
Reflection
Thank you very much for following along for my project stage 1. This project did take me a while but it reinforced my understanding the role GCC plays as well as gcc passes. In addition, I ran into several bottlenecks like incorrect headers in the gcc pass, incorrect naming, etc. I also made an incorrect build of my gcc-test-001 which was not picking up my pass. I took the time to diagnose the issue and was finally successful. Overall, I found it hard at first but now I feel like I can add more passes.
References
- Credit goes to Professor Chris Tyler’s lecture and SPO600 wiki
Subscribe to my newsletter
Read articles from Hamza Teli directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
