| @c Copyright (c) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. |
| @c Free Software Foundation, Inc. |
| @c This is part of the GCC manual. |
| @c For copying conditions, see the file gcc.texi. |
| |
| @c --------------------------------------------------------------------- |
| @c GENERIC |
| @c --------------------------------------------------------------------- |
| |
| @node GENERIC |
| @chapter GENERIC |
| @cindex GENERIC |
| |
| The purpose of GENERIC is simply to provide a |
| language-independent way of representing an entire function in |
| trees. To this end, it was necessary to add a few new tree codes |
| to the back end, but most everything was already there. If you |
| can express it with the codes in @code{gcc/tree.def}, it's |
| GENERIC@. |
| |
| Early on, there was a great deal of debate about how to think |
| about statements in a tree IL@. In GENERIC, a statement is |
| defined as any expression whose value, if any, is ignored. A |
| statement will always have @code{TREE_SIDE_EFFECTS} set (or it |
| will be discarded), but a non-statement expression may also have |
| side effects. A @code{CALL_EXPR}, for instance. |
| |
| It would be possible for some local optimizations to work on the |
| GENERIC form of a function; indeed, the adapted tree inliner |
| works fine on GENERIC, but the current compiler performs inlining |
| after lowering to GIMPLE (a restricted form described in the next |
| section). Indeed, currently the frontends perform this lowering |
| before handing off to @code{tree_rest_of_compilation}, but this |
| seems inelegant. |
| |
| If necessary, a front end can use some language-dependent tree |
| codes in its GENERIC representation, so long as it provides a |
| hook for converting them to GIMPLE and doesn't expect them to |
| work with any (hypothetical) optimizers that run before the |
| conversion to GIMPLE@. The intermediate representation used while |
| parsing C and C++ looks very little like GENERIC, but the C and |
| C++ gimplifier hooks are perfectly happy to take it as input and |
| spit out GIMPLE@. |
| |
| @menu |
| * Statements:: |
| @end menu |
| |
| @node Statements |
| @section Statements |
| @cindex Statements |
| |
| Most statements in GIMPLE are assignment statements, represented by |
| @code{GIMPLE_ASSIGN}. No other C expressions can appear at statement level; |
| a reference to a volatile object is converted into a |
| @code{GIMPLE_ASSIGN}. |
| |
| There are also several varieties of complex statements. |
| |
| @menu |
| * Blocks:: |
| * Statement Sequences:: |
| * Empty Statements:: |
| * Jumps:: |
| * Cleanups:: |
| @end menu |
| |
| @node Blocks |
| @subsection Blocks |
| @cindex Blocks |
| |
| Block scopes and the variables they declare in GENERIC are |
| expressed using the @code{BIND_EXPR} code, which in previous |
| versions of GCC was primarily used for the C statement-expression |
| extension. |
| |
| Variables in a block are collected into @code{BIND_EXPR_VARS} in |
| declaration order. Any runtime initialization is moved out of |
| @code{DECL_INITIAL} and into a statement in the controlled block. |
| When gimplifying from C or C++, this initialization replaces the |
| @code{DECL_STMT}. |
| |
| Variable-length arrays (VLAs) complicate this process, as their |
| size often refers to variables initialized earlier in the block. |
| To handle this, we currently split the block at that point, and |
| move the VLA into a new, inner @code{BIND_EXPR}. This strategy |
| may change in the future. |
| |
| A C++ program will usually contain more @code{BIND_EXPR}s than |
| there are syntactic blocks in the source code, since several C++ |
| constructs have implicit scopes associated with them. On the |
| other hand, although the C++ front end uses pseudo-scopes to |
| handle cleanups for objects with destructors, these don't |
| translate into the GIMPLE form; multiple declarations at the same |
| level use the same @code{BIND_EXPR}. |
| |
| @node Statement Sequences |
| @subsection Statement Sequences |
| @cindex Statement Sequences |
| |
| Multiple statements at the same nesting level are collected into |
| a @code{STATEMENT_LIST}. Statement lists are modified and |
| traversed using the interface in @samp{tree-iterator.h}. |
| |
| @node Empty Statements |
| @subsection Empty Statements |
| @cindex Empty Statements |
| |
| Whenever possible, statements with no effect are discarded. But |
| if they are nested within another construct which cannot be |
| discarded for some reason, they are instead replaced with an |
| empty statement, generated by @code{build_empty_stmt}. |
| Initially, all empty statements were shared, after the pattern of |
| the Java front end, but this caused a lot of trouble in practice. |
| |
| An empty statement is represented as @code{(void)0}. |
| |
| @node Jumps |
| @subsection Jumps |
| @cindex Jumps |
| |
| Other jumps are expressed by either @code{GOTO_EXPR} or |
| @code{RETURN_EXPR}. |
| |
| The operand of a @code{GOTO_EXPR} must be either a label or a |
| variable containing the address to jump to. |
| |
| The operand of a @code{RETURN_EXPR} is either @code{NULL_TREE}, |
| @code{RESULT_DECL}, or a @code{MODIFY_EXPR} which sets the return |
| value. It would be nice to move the @code{MODIFY_EXPR} into a |
| separate statement, but the special return semantics in |
| @code{expand_return} make that difficult. It may still happen in |
| the future, perhaps by moving most of that logic into |
| @code{expand_assignment}. |
| |
| @node Cleanups |
| @subsection Cleanups |
| @cindex Cleanups |
| |
| Destructors for local C++ objects and similar dynamic cleanups are |
| represented in GIMPLE by a @code{TRY_FINALLY_EXPR}. |
| @code{TRY_FINALLY_EXPR} has two operands, both of which are a sequence |
| of statements to execute. The first sequence is executed. When it |
| completes the second sequence is executed. |
| |
| The first sequence may complete in the following ways: |
| |
| @enumerate |
| |
| @item Execute the last statement in the sequence and fall off the |
| end. |
| |
| @item Execute a goto statement (@code{GOTO_EXPR}) to an ordinary |
| label outside the sequence. |
| |
| @item Execute a return statement (@code{RETURN_EXPR}). |
| |
| @item Throw an exception. This is currently not explicitly represented in |
| GIMPLE. |
| |
| @end enumerate |
| |
| The second sequence is not executed if the first sequence completes by |
| calling @code{setjmp} or @code{exit} or any other function that does |
| not return. The second sequence is also not executed if the first |
| sequence completes via a non-local goto or a computed goto (in general |
| the compiler does not know whether such a goto statement exits the |
| first sequence or not, so we assume that it doesn't). |
| |
| After the second sequence is executed, if it completes normally by |
| falling off the end, execution continues wherever the first sequence |
| would have continued, by falling off the end, or doing a goto, etc. |
| |
| @code{TRY_FINALLY_EXPR} complicates the flow graph, since the cleanup |
| needs to appear on every edge out of the controlled block; this |
| reduces the freedom to move code across these edges. Therefore, the |
| EH lowering pass which runs before most of the optimization passes |
| eliminates these expressions by explicitly adding the cleanup to each |
| edge. Rethrowing the exception is represented using @code{RESX_EXPR}. |