These are rough notes only! Unfortunately, this part of the GCC codebase is poorly documented at this point in time.
GCC passes are used to transform code. Initially, the input source code is transformed into GLIMPSE, then into GIMPLE, then into RTL, and finally into assembly for the target system.
Passes are defined in the gcc
subdirectory. (It is important to note that both the top-level directory and the gcc subdirectory share the gcc
name, so we're specifically referring to the second-level directory here!).
Passes are controlled by the pass manager, which handles sequencing of passes, creation of dump files, and various setup/cleanup operations.
The pass manager uses the file passes.def
to define the order in which passes are called. This file is processed by the script gen-pass-instances.awk
to create the file pass-instances.def
, which is then subject to macro expansion (using macros defined in pass_manager.h
) and included into passes.cc
.
The macros used in this file permit both passes and sub-passes to be defined.
The most basic way to add a new pass into this file is to define NEXT_PASS (name_of_pass)
to insert a pass at a specific point in the pass list, or as a sub-pass within a pass group.
Each pass provides a C++ source file which provides:
pass_data
structure which defines the pass details (defined in tree-pass.h
);gimple_opt_pass
and includes the public methods gate
and execute
.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.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!).make_pass_name
which returns a pointer to the gimple_opt_pass
described above.
In order to cause a new pass to be built and used, after having added the source code for your pass and adding the pass to passes.def
, you must:
Makefile.in
in the OBJS =
(object files) section. For example, if your source file is tree-footest.cc
, add tree-footest.o
to the OBJS list.make_pass_name
to the tree-pass.h
header file.
Important: you must re-create the Makefile
in the gcc subdirectory of your build tree in order for changes in the Makefile.in
to be recognized – the build system will not automatically detect changes to the Makefile.in
. The easiest way to do this without rebuilding everything is to delete the Makefile
in the gcc subdirectory of your build tree. You do not need to do this unless you have made changes to the Makefile.in
.
There are a number of macros defined in cgraph.h
which may be used to walk through the callgraph of the IR tree:
There are also a number of macros defined in basic-block.h
which may be used to interate through the basic blocks of a function:
There are a group of functions defined in gimple-iterator.h
which may be used to constuct for( , , )
loops that iterate through gimple statements. For example:
for ( gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next(&gsi) )
pass_data
structure does not start with an astrisk (*).dump_file
file descriptor like this:if (dump_file) { fprintf (dump_file, ... ); }
This section will be extended – watch for changes.