============================================ Introduction to Gray Box Probing Assignments ============================================ In this series of simple C programs we look at different aspects of the GIMPLE representation of programs by considering several small programs and their corresponding GIMPLE statements created by gcc. In these programs we will exercise different programming features and understand various shades of the gimplification process. Note that we are interested in "how a language feature compiles into GIMPLEs", do not look into what the program is achieving. In most of the cases the programs will be meaningless (and/or wrong! :). The first section deals with compilation of various C language features. The second section deals with some optimization features. The names of our test programs should give you some idea of the features we would be concentrating on. You do not have to necessarily know the optimizations; the problem statements explain them. Where they are not clear, feel free to ask any Teaching Assistant. ------- ----------------------------------------------- Program Feature ------- ----------------------------------------------- a1ve Variables and Expressions a2if Conditional Jumps and Control Flow Graphs a3lo Loops a4ap Arrays and Pointers a5ss Static Single Assignment ------- ----------------------------------------------- Program Optimization ------- ----------------------------------------------- b1cs Common Subexpression Elimination b2pr Loop Invariant Code Motion b3lu Loop Unrolling b4fi Function Inlining ------- ----------------------------------------------- ======================= Section A: GIMPLE dumps ======================= In order to produce the dumps of intermediate stages of the compilation process, the following options are useful: -fdump-tree-all Dump all GIMPLE passes -fdump-ipa-all Dump all Inter-Procedural Analysis passes -fdump-rtl-all Dump all RTL passes In each case the word "all" can be substituted with a pass name (if you know it) to generate a dump for only that pass. For now we are only interested in observing GIMPLE so we will use the first option. Try using this option while compiling the first exercise and see the generated files: $ gcc -c a1ve.c -fdump-tree-all $ ls a1ve.c a1ve.c.012t.eh a1ve.c.038t.inline_param2 a1ve.c.001t.tu a1ve.c.013t.cfg a1ve.c.138t.cplxlower0 a1ve.c.003t.original a1ve.c.017t.ssa a1ve.c.143t.optimized a1ve.c.004t.gimple a1ve.c.018t.veclower a1ve.c.224t.statistics a1ve.c.006t.vcg a1ve.c.019t.inline_param1 a1ve.o a1ve.c.009t.omplower a1ve.c.020t.einline a1ve.c.010t.lower a1ve.c.037t.release_ssa Each dump file corresponds to a GIMPLE pass and is named as ... The exact numbering might differ in different versions of GCC so it is best to use wild-cards when trying to open the file for a particular pass. For example, to view the pass named "veclower" type: $ vi a1ve.c.*.veclower Each time you are done with an exercise, you can clear the generated files using something like: $ rm -f a1ve.o a1ve.c.* This will remove the compiled object (a1ve.o) and all the dumps (a1ve.c.*). Important: Note the dot before the * to avoid removing the source file (a1ve.c) Some notable passes are: Pass Name Function --------- -------- gimple Conversion of original C source to GIMPLE cfg Construction of Control Flow Graph (CFG) ssa Conversion to Static Single Assignment (SSA) form optimized The final result after all GIMPLE optimizations All passes between "ssa" and "optimized" are usually optimization passes which we will come to in section B of this assignment. =================================== Section B: Optimizations on GIMPLE =================================== Before we start with the individual exercises, just a little note on GCC's various optimization levels. To enable optimizations, supply GCC with a flag: either -O1, -O2 or -O3. The option -O0 suppresses all optimizations whereas the option -Os improves the program for space. These levels enable a set of additional passes to execute. Each optimization level has a different trade-off between compilation time, generated code size and generated code speed. You can even enable individual passes using the corresponding "-ftree-" option e.g. "-ftree-dce" enables Dead Code Elimination. See (http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html) for more info. As an exercise, pick any file and look at all the dumps generated at different optimization levels: rm -f *.c.* # Remove previous dumps gcc -c b1cs.c -fdump-tree-all # Any file will do ls *.c.* # Look at the list of passes rm -f *.c.* # Remove previous dumps gcc -c b1cs.c -fdump-tree-all -O1 # Compile with O1 ls *.c.* # More passes? rm -f *.c.* # Remove previous dumps gcc -c b1cs.c -fdump-tree-all -O2 # Compile with O2 ls *.c.* # More passes? rm -f *.c.* # Remove previous dumps gcc -c b1cs.c -fdump-tree-all -O3 # Compile with O3 ls *.c.* # More passes? rm -f *.c.* # Remove previous dumps A complete list of optimizations with a brief description can be found by giving the command: $ gcc -c --help=optimizers To find out which optimizations are enabled at level 2 (other levels are 0, 1, 3, and s) use the command: $ gcc -c -O2 --help=optimizers -Q You may use "ls *.c.* | wc -l" to count the number of dumps instead of viewing the entire list.