411 REFERENCE · Wikibooks
GNU C Compiler Internals/Compilation of a function 4 1
Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.
Function Prolog and Epilog
232px|center|GCC stack frame layout.
A prolog is used to initialize the function, for example set up its
stack frame. A function epilog is used to finalize execution. At each
level of compilation, there are common actions performed for each
function. Therefore, a number of prolog/epilog generation functions
exist in GCC.
At the GIMPLE level prolog is generated in function
gimplify_function_tree(). It adds profiling hooks if instructed so
using -finstrument-functions.
At the RTL level, function expand_function_start is used. It starts
the RTL for a new function, and set variables used for
emitting RTL. It also makes the label for return statements to jump to
and decides whether to return the value in memory or in a
register. After this, it calls assign_parms() which maps the
formal-ins to the actual-ins.
Machine-level prolog and epilog are added in pass flow2, function
thread_prologue_and_epilogue_insns() which relies upon machine description
file, for example i386.md. The description has a number of
entries. The prolog and epilog entries is used in this case. They are set to
ix86_expand_prologue() and ix86_expand_epilogue() respectively that
generate RTL prologue and
epilog for i386 architecture. The machine-specific code takes care of
registered used in the function so that they are preserved between
function calls. The push instructions are added as the very first
instructions of a function.
The machine-specific code is generated as an RTL expression rather
than assembly because this is the representation used at this pass of
the compiler. The RTL representation is the most general across various
targets. Therefore, a push instruction of i386 corresponds
to a number of RTL expressions:
static rtx
gen_push (rtx arg)
{
return gen_rtx_SET (VOIDmode,
gen_rtx_MEM (Pmode,
gen_rtx_PRE_DEC (Pmode,
stack_pointer_rtx)),
arg);
}
At the assembly output level, prolog is generated in functions
assemble_start_function() and final_start_function(). Their output is mostly
related to debugging.
One should note that the prolog functions are executed from the
higher-level representation to the lower-level ones. At the run-time,
the execution order of the added code is opposite. That is, the
machine-level prolog is executed first. In case of i386, it saves the
registers used in the function and sets up a new stack frame. Then the
parameters are received and the profiling hooks are called.
Local Control Flow Analysis
A control-flow graph is built up of basic blocks which is a sequence
of instructions with only one entry and one exit. Type struct
basic_block describes it. There is a pointer to the statement list
that defines the basic block. Each basic block also has a pointer to
the previous and next BB. Therefore, it is possible to link them in a
list. Fields preds and succs give access to control/data flow
edges into and out of the block.
Function create_basic_block() takes the first and the last statements
and inserts the new BB after a given one. make_edge() links the two
BBs.
Use macro FOR_EACH_BB to traverse a CFG. Each function flow graph has
an entry and an exit block accessed using ENTRY_BLOCK_PTR and
EXIT_BLOCK_PTR respectively.
Function build_tree_cfg() takes a GIMPLE tree and generates the
CFG. First, it initializes the CFG with two BBs: ENTRY_BLOCK and EXIT_BLOCK. It calls make_blocks(), then make_edges().