GIMPLE is a three-address representation derived from GENERIC by
breaking down GENERIC expressions into tuples of no more than 3
operands (with some exceptions like function calls). GIMPLE was
heavily influenced by the SIMPLE IL used by the McCAT compiler
project at McGill University, though we have made some different
choices. For one thing, SIMPLE doesn't support goto.
Temporaries are introduced to hold intermediate values needed to compute complex expressions. Additionally, all the control structures used in GENERIC are lowered into conditional jumps, lexical scopes are removed and exception regions are converted into an on the side exception region tree.
The compiler pass which converts GENERIC into GIMPLE is referred to as the `gimplifier'. The gimplifier works recursively, generating GIMPLE tuples out of the original GENERIC expressions.
One of the early implementation strategies used for the GIMPLE representation was to use the same internal data structures used by front ends to represent parse trees. This simplified implementation because we could leverage existing functionality and interfaces. However, GIMPLE is a much more restrictive representation than abstract syntax trees (AST), therefore it does not require the full structural complexity provided by the main tree data structure.
The GENERIC representation of a function is stored in the
DECL_SAVED_TREE field of the associated FUNCTION_DECL
tree node. It is converted to GIMPLE by a call to
gimplify_function_tree.
If a front end wants to include language-specific tree codes in the tree
representation which it provides to the back end, it must provide a
definition of LANG_HOOKS_GIMPLIFY_EXPR which knows how to
convert the front end trees to GIMPLE. Usually such a hook will involve
much of the same code for expanding front end trees to RTL. This function
can return fully lowered GIMPLE, or it can return GENERIC trees and let the
main gimplifier lower them the rest of the way; this is often simpler.
GIMPLE that is not fully lowered is known as “High GIMPLE” and
consists of the IL before the pass pass_lower_cf. High GIMPLE
contains some container statements like lexical scopes
(represented by GIMPLE_BIND) and nested expressions (e.g.,
GIMPLE_TRY), while “Low GIMPLE” exposes all of the
implicit jumps for control and exception expressions directly in
the IL and EH region trees.
The C and C++ front ends currently convert directly from front end
trees to GIMPLE, and hand that off to the back end rather than first
converting to GENERIC. Their gimplifier hooks know about all the
_STMT nodes and how to convert them to GENERIC forms. There
was some work done on a genericization pass which would run first, but
the existence of STMT_EXPR meant that in order to convert all
of the C statements into GENERIC equivalents would involve walking the
entire tree anyway, so it was simpler to lower all the way. This
might change in the future if someone writes an optimization pass
which would work better with higher-level trees, but currently the
optimizers all expect GIMPLE.
You can request to dump a C-like representation of the GIMPLE form with the flag -fdump-tree-gimple.
GIMPLE instructions are tuples of variable size divided in two groups: a header describing the instruction and its locations, and a variable length body with all the operands. Tuples are organized into a hierarchy with 3 main classes of tuples.
gimple_statement_base (gsbase)This is the root of the hierarchy, it holds basic information needed by most GIMPLE statements. There are some fields that may not be relevant to every GIMPLE statement, but those were moved into the base structure to take advantage of holes left by other fields (thus making the structure more compact). The structure takes 4 words (32 bytes) on 64 bit hosts:
| Field | Size (bits)
|
code | 8
|
subcode | 16
|
no_warning | 1
|
visited | 1
|
nontemporal_move | 1
|
plf | 2
|
modified | 1
|
has_volatile_ops | 1
|
references_memory_p | 1
|
uid | 32
|
location | 32
|
num_ops | 32
|
bb | 64
|
block | 63
|
| Total size | 32 bytes
|
code
Main identifier for a GIMPLE instruction.
subcode
Used to distinguish different variants of the same basic
instruction or provide flags applicable to a given code. The
subcode flags field has different uses depending on the code of
the instruction, but mostly it distinguishes instructions of the
same family. The most prominent use of this field is in
assignments, where subcode indicates the operation done on the
RHS of the assignment. For example, a = b + c is encoded as
GIMPLE_ASSIGN <PLUS_EXPR, a, b, c>.
no_warning
Bitflag to indicate whether a warning has already been issued on
this statement.
visited
General purpose “visited” marker. Set and cleared by each pass
when needed.
nontemporal_move
Bitflag used in assignments that represent non-temporal moves.
Although this bitflag is only used in assignments, it was moved
into the base to take advantage of the bit holes left by the
previous fields.
plf
Pass Local Flags. This 2-bit mask can be used as general purpose
markers by any pass. Passes are responsible for clearing and
setting these two flags accordingly.
modified
Bitflag to indicate whether the statement has been modified.
Used mainly by the operand scanner to determine when to re-scan a
statement for operands.
has_volatile_ops
Bitflag to indicate whether this statement contains operands that
have been marked volatile.
references_memory_p
Bitflag to indicate whether this statement contains memory
references (i.e., its operands are either global variables, or
pointer dereferences or anything that must reside in memory).
uid
This is an unsigned integer used by passes that want to assign
IDs to every statement. These IDs must be assigned and used by
each pass.
location
This is a location_t identifier to specify source code
location for this statement. It is inherited from the front
end.
num_ops
Number of operands that this statement has. This specifies the
size of the operand vector embedded in the tuple. Only used in
some tuples, but it is declared in the base tuple to take
advantage of the 32-bit hole left by the previous fields.
bb
Basic block holding the instruction.
block
Lexical block holding this statement. Also used for debug
information generation.
gimple_statement_with_ops
This tuple is actually split in two:
gimple_statement_with_ops_base and
gimple_statement_with_ops. This is needed to accommodate the
way the operand vector is allocated. The operand vector is
defined to be an array of 1 element. So, to allocate a dynamic
number of operands, the memory allocator (gimple_alloc) simply
allocates enough memory to hold the structure itself plus N
- 1 operands which run “off the end” of the structure. For
example, to allocate space for a tuple with 3 operands,
gimple_alloc reserves sizeof (struct
gimple_statement_with_ops) + 2 * sizeof (tree) bytes.
On the other hand, several fields in this tuple need to be shared
with the gimple_statement_with_memory_ops tuple. So, these
common fields are placed in gimple_statement_with_ops_base which
is then inherited from the other two tuples.
gsbase | 256
|
addresses_taken | 64
|
def_ops | 64
|
use_ops | 64
|
op | num_ops * 64
|
| Total size | 56 + 8 * num_ops bytes
|
gsbase
Inherited from struct gimple_statement_base.
addresses_taken
Bitmap holding the UIDs of all the VAR_DECLs whose addresses are
taken by this statement. For example, a statement of the form
p = &b will have the UID for symbol b in this set.
def_ops
Array of pointers into the operand array indicating all the slots that
contain a variable written-to by the statement. This array is
also used for immediate use chaining. Note that it would be
possible to not rely on this array, but the changes required to
implement this are pretty invasive.
use_ops
Similar to def_ops but for variables read by the statement.
op
Array of trees with num_ops slots.
gimple_statement_with_memory_opsThis tuple is essentially identical to gimple_statement_with_ops,
except that it contains 4 additional fields to hold vectors
related memory stores and loads. Similar to the previous case,
the structure is split in two to accommodate for the operand
vector (gimple_statement_with_memory_ops_base and
gimple_statement_with_memory_ops).
| Field | Size (bits)
|
gsbase | 256
|
addresses_taken | 64
|
def_ops | 64
|
use_ops | 64
|
vdef_ops | 64
|
vuse_ops | 64
|
stores | 64
|
loads | 64
|
op | num_ops * 64
|
| Total size | 88 + 8 * num_ops bytes
|
vdef_ops
Similar to def_ops but for VDEF operators. There is
one entry per memory symbol written by this statement. This is
used to maintain the memory SSA use-def and def-def chains.
vuse_ops
Similar to use_ops but for VUSE operators. There is
one entry per memory symbol loaded by this statement. This is
used to maintain the memory SSA use-def chains.
stores
Bitset with all the UIDs for the symbols written-to by the
statement. This is different than vdef_ops in that all the
affected symbols are mentioned in this set. If memory
partitioning is enabled, the vdef_ops vector will refer to memory
partitions. Furthermore, no SSA information is stored in this
set.
loads
Similar to stores, but for memory loads. (Note that there
is some amount of redundancy here, it should be possible to
reduce memory utilization further by removing these sets).
All the other tuples are defined in terms of these three basic
ones. Each tuple will add some fields. The main gimple type
is defined to be the union of all these structures (GTY markers
elided for clarity):
union gimple_statement_d
{
struct gimple_statement_base gsbase;
struct gimple_statement_with_ops gsops;
struct gimple_statement_with_memory_ops gsmem;
struct gimple_statement_omp omp;
struct gimple_statement_bind gimple_bind;
struct gimple_statement_catch gimple_catch;
struct gimple_statement_eh_filter gimple_eh_filter;
struct gimple_statement_phi gimple_phi;
struct gimple_statement_resx gimple_resx;
struct gimple_statement_try gimple_try;
struct gimple_statement_wce gimple_wce;
struct gimple_statement_asm gimple_asm;
struct gimple_statement_omp_critical gimple_omp_critical;
struct gimple_statement_omp_for gimple_omp_for;
struct gimple_statement_omp_parallel gimple_omp_parallel;
struct gimple_statement_omp_task gimple_omp_task;
struct gimple_statement_omp_sections gimple_omp_sections;
struct gimple_statement_omp_single gimple_omp_single;
struct gimple_statement_omp_continue gimple_omp_continue;
struct gimple_statement_omp_atomic_load gimple_omp_atomic_load;
struct gimple_statement_omp_atomic_store gimple_omp_atomic_store;
};
The following table briefly describes the GIMPLE instruction set.
| Instruction | High GIMPLE | Low GIMPLE
|
GIMPLE_ASM | x | x
|
GIMPLE_ASSIGN | x | x
|
GIMPLE_BIND | x |
|
GIMPLE_CALL | x | x
|
GIMPLE_CATCH | x |
|
GIMPLE_CHANGE_DYNAMIC_TYPE | x | x
|
GIMPLE_COND | x | x
|
GIMPLE_EH_FILTER | x |
|
GIMPLE_GOTO | x | x
|
GIMPLE_LABEL | x | x
|
GIMPLE_NOP | x | x
|
GIMPLE_OMP_ATOMIC_LOAD | x | x
|
GIMPLE_OMP_ATOMIC_STORE | x | x
|
GIMPLE_OMP_CONTINUE | x | x
|
GIMPLE_OMP_CRITICAL | x | x
|
GIMPLE_OMP_FOR | x | x
|
GIMPLE_OMP_MASTER | x | x
|
GIMPLE_OMP_ORDERED | x | x
|
GIMPLE_OMP_PARALLEL | x | x
|
GIMPLE_OMP_RETURN | x | x
|
GIMPLE_OMP_SECTION | x | x
|
GIMPLE_OMP_SECTIONS | x | x
|
GIMPLE_OMP_SECTIONS_SWITCH | x | x
|
GIMPLE_OMP_SINGLE | x | x
|
GIMPLE_PHI | x
| |
GIMPLE_RESX | x
| |
GIMPLE_RETURN | x | x
|
GIMPLE_SWITCH | x | x
|
GIMPLE_TRY | x |
|
Other exception handling constructs are represented using
GIMPLE_TRY_CATCH. GIMPLE_TRY_CATCH has two operands. The
first operand is a sequence of statements to execute. If executing
these statements does not throw an exception, then the second operand
is ignored. Otherwise, if an exception is thrown, then the second
operand of the GIMPLE_TRY_CATCH is checked. The second
operand may have the following forms:
GIMPLE_CATCH statements. Each
GIMPLE_CATCH has a list of applicable exception types and
handler code. If the thrown exception matches one of the caught
types, the associated handler code is executed. If the handler
code falls off the bottom, execution continues after the original
GIMPLE_TRY_CATCH.
GIMPLE_EH_FILTER statement. This has a list of
permitted exception types, and code to handle a match failure. If the
thrown exception does not match one of the allowed types, the
associated match failure code is executed. If the thrown exception
does match, it continues unwinding the stack looking for the next
handler.
Currently throwing an exception is not directly represented in GIMPLE, since it is implemented by calling a function. At some point in the future we will want to add some way to express that the call will throw an exception of a known type.
Just before running the optimizers, the compiler lowers the
high-level EH constructs above into a set of `goto's, magic
labels, and EH regions. Continuing to unwind at the end of a
cleanup is represented with a GIMPLE_RESX.
When gimplification encounters a subexpression that is too
complex, it creates a new temporary variable to hold the value of
the subexpression, and adds a new statement to initialize it
before the current statement. These special temporaries are known
as `expression temporaries', and are allocated using
get_formal_tmp_var. The compiler tries to always evaluate
identical expressions into the same temporary, to simplify
elimination of redundant calculations.
We can only use expression temporaries when we know that it will
not be reevaluated before its value is used, and that it will not
be otherwise modified1. Other temporaries can be allocated
using get_initialized_tmp_var or create_tmp_var.
Currently, an expression like a = b + 5 is not reduced any
further. We tried converting it to something like
T1 = b + 5;
a = T1;
but this bloated the representation for minimal benefit. However, a variable which must live in memory cannot appear in an expression; its value is explicitly loaded into a temporary first. Similarly, storing the value of an expression to a memory variable goes through a temporary.
In general, expressions in GIMPLE consist of an operation and the
appropriate number of simple operands; these operands must either be a
GIMPLE rvalue (is_gimple_val), i.e. a constant or a register
variable. More complex operands are factored out into temporaries, so
that
a = b + c + d
becomes
T1 = b + c;
a = T1 + d;
The same rule holds for arguments to a GIMPLE_CALL.
The target of an assignment is usually a variable, but can also be an
INDIRECT_REF or a compound lvalue as described below.
The left-hand side of a C comma expression is simply moved into a separate statement.
Currently compound lvalues involving array and structure field references
are not broken down; an expression like a.b[2] = 42 is not reduced
any further (though complex array subscripts are). This restriction is a
workaround for limitations in later optimizers; if we were to convert this
to
T1 = &a.b;
T1[2] = 42;
alias analysis would not remember that the reference to T1[2] came
by way of a.b, so it would think that the assignment could alias
another member of a; this broke struct-alias-1.c. Future
optimizer improvements may make this limitation unnecessary.
A C ?: expression is converted into an if statement with
each branch assigning to the same temporary. So,
a = b ? c : d;
becomes
if (b == 1)
T1 = c;
else
T1 = d;
a = T1;
The GIMPLE level if-conversion pass re-introduces ?:
expression, if appropriate. It is used to vectorize loops with
conditions using vector conditional operations.
Note that in GIMPLE, if statements are represented using
GIMPLE_COND, as described below.
Except when they appear in the condition operand of a
GIMPLE_COND, logical `and' and `or' operators are simplified
as follows: a = b && c becomes
T1 = (bool)b;
if (T1 == true)
T1 = (bool)c;
a = T1;
Note that T1 in this example cannot be an expression temporary,
because it has two different assignments.
All gimple operands are of type tree. But only certain
types of trees are allowed to be used as operand tuples. Basic
validation is controlled by the function
get_gimple_rhs_class, which given a tree code, returns an
enum with the following values of type enum
gimple_rhs_class
GIMPLE_INVALID_RHS
The tree cannot be used as a GIMPLE operand.
GIMPLE_BINARY_RHS
The tree is a valid GIMPLE binary operation.
GIMPLE_UNARY_RHS
The tree is a valid GIMPLE unary operation.
GIMPLE_SINGLE_RHS
The tree is a single object, that cannot be split into simpler
operands (for instance, SSA_NAME, VAR_DECL, COMPONENT_REF, etc).
This operand class also acts as an escape hatch for tree nodes
that may be flattened out into the operand vector, but would need
more than two slots on the RHS. For instance, a COND_EXPR
expression of the form (a op b) ? x : y could be flattened
out on the operand vector using 4 slots, but it would also
require additional processing to distinguish c = a op b
from c = a op b ? x : y. Something similar occurs with
ASSERT_EXPR. In time, these special case tree
expressions should be flattened into the operand vector.
For tree nodes in the categories GIMPLE_BINARY_RHS and
GIMPLE_UNARY_RHS, they cannot be stored inside tuples directly.
They first need to be flattened and separated into individual
components. For instance, given the GENERIC expression
a = b + c
its tree representation is:
MODIFY_EXPR <VAR_DECL <a>, PLUS_EXPR <VAR_DECL <b>, VAR_DECL <c>>>
In this case, the GIMPLE form for this statement is logically
identical to its GENERIC form but in GIMPLE, the PLUS_EXPR
on the RHS of the assignment is not represented as a tree,
instead the two operands are taken out of the PLUS_EXPR sub-tree
and flattened into the GIMPLE tuple as follows:
GIMPLE_ASSIGN <PLUS_EXPR, VAR_DECL <a>, VAR_DECL <b>, VAR_DECL <c>>
The operand vector is stored at the bottom of the three tuple structures that accept operands. This means, that depending on the code of a given statement, its operand vector will be at different offsets from the base of the structure. To access tuple operands use the following accessors
Returns the number of operands in statement G.
Returns a pointer into the operand vector for statement
G. This is computed using an internal table calledgimple_ops_offset_[]. This table is indexed by the gimple code ofG.When the compiler is built, this table is filled-in using the sizes of the structures used by each statement code defined in gimple.def. Since the operand vector is at the bottom of the structure, for a gimple code
Cthe offset is computed as sizeof (struct-ofC) - sizeof (tree).This mechanism adds one memory indirection to every access when using
gimple_op(), if this becomes a bottleneck, a pass can choose to memoize the result fromgimple_ops() and use that to access the operands.
When adding a new operand to a gimple statement, the operand will
be validated according to what each tuple accepts in its operand
vector. These predicates are called by the
gimple_<name>_set_...(). Each tuple will use one of the
following predicates (Note, this list is not exhaustive):
This is the most permissive of the predicates. It essentially checks whether t has a
gimple_rhs_classofGIMPLE_SINGLE_RHS.
Returns true if t is a "GIMPLE value", which are all the non-addressable stack variables (variables for which
is_gimple_regreturns true) and constants (expressions for whichis_gimple_min_invariantreturns true).
Returns true if t is a symbol or memory reference whose address can be taken.
Similar to
is_gimple_valbut it also accepts hard registers.
Return true if t is a valid expression to use as the function called by a
GIMPLE_CALL.
Return true if t is a valid minimal invariant. This is different from constants, in that the specific value of t may not be known at compile time, but it is known that it doesn't change (e.g., the address of a function local variable).
Return true if t is an
ADDR_EXPRthat does not change once the program is running.
Return true if g is a
GIMPLE_ASSIGNthat performs a type cast operation
This section documents all the functions available to handle each of the GIMPLE instructions.
The following are common accessors for gimple statements.
Return the basic block to which statement
Gbelongs to.
Return the type of the main expression computed by
STMT. Returnvoid_type_nodeifSTMTcomputes nothing. This will only return something meaningful forGIMPLE_ASSIGN,GIMPLE_CONDandGIMPLE_CALL. For all other tuple codes, it will returnvoid_type_node.
Return the tree code for the expression computed by
STMT. This is only meaningful forGIMPLE_CALL,GIMPLE_ASSIGNandGIMPLE_COND. IfSTMTisGIMPLE_CALL, it will returnCALL_EXPR. ForGIMPLE_COND, it returns the code of the comparison predicate. ForGIMPLE_ASSIGNit returns the code of the operation performed by theRHSof the assignment.
Set the lexical scope block of
GtoBLOCK.
Set locus information for statement
G.
Return true if
Gdoes not have locus information.
Return true if no warnings should be emitted for statement
STMT.
Set the visited status on statement
STMTtoVISITED_P.
Set pass local flag
PLFon statementSTMTtoVAL_P.
Return the value of pass local flag
PLFon statementSTMT.
Return true if statement
Ghas register or memory operands.
Return true if statement
Ghas memory operands.
Return the number of operands for statement
G.
Return a pointer to operand
Ifor statementG.
Set operand
Iof statementGtoOP.
Return the set of symbols that have had their address taken by
STMT.
Return the set of
DEFoperands for statementG.
Set
DEFto be the set ofDEFoperands for statementG.
Return the set of
USEoperands for statementG.
Set
USEto be the set ofUSEoperands for statementG.
Return the set of
VUSEoperands for statementG.
Set
OPSto be the set ofVUSEoperands for statementG.
Return the set of
VDEFoperands for statementG.
Set
OPSto be the set ofVDEFoperands for statementG.
Return the set of symbols loaded by statement
G. Each element of the set is theDECL_UIDof the corresponding symbol.
Return the set of symbols stored by statement
G. Each element of the set is theDECL_UIDof the corresponding symbol.
Return true if statement
Ghas operands and the modified field has been set.
Return true if statement
STMTcontains volatile operands.
Return true if statement
STMTcontains volatile operands.
Update statement
Sif it has been marked modified.
GIMPLE_ASMBuild a
GIMPLE_ASMstatement. This statement is used for building in-line assembly constructs.STRINGis the assembly code.NINPUTis the number of register inputs.NOUTPUTis the number of register outputs.NCLOBBERSis the number of clobbered registers. The rest of the arguments trees for each input, output, and clobbered registers.
Identical to gimple_build_asm, but the arguments are passed in VECs.
Return the number of input operands for
GIMPLE_ASMG.
Return the number of output operands for
GIMPLE_ASMG.
Return the number of clobber operands for
GIMPLE_ASMG.
Return input operand
INDEXofGIMPLE_ASMG.
Set
IN_OPto be input operandINDEXinGIMPLE_ASMG.
Return output operand
INDEXofGIMPLE_ASMG.
Set
OUT_OPto be output operandINDEXinGIMPLE_ASMG.
Return clobber operand
INDEXofGIMPLE_ASMG.
Set
CLOBBER_OPto be clobber operandINDEXinGIMPLE_ASMG.
Return the string representing the assembly instruction in
GIMPLE_ASMG.
Return true if
Gis an asm statement marked volatile.
Remove volatile marker from asm statement
G.
GIMPLE_ASSIGNBuild a
GIMPLE_ASSIGNstatement. The left-hand side is an lvalue passed in lhs. The right-hand side can be either a unary or binary tree expression. The expression tree rhs will be flattened and its operands assigned to the corresponding operand slots in the new statement. This function is useful when you already have a tree expression that you want to convert into a tuple. However, try to avoid building expression trees for the sole purpose of calling this function. If you already have the operands in separate trees, it is better to usegimple_build_assign_with_ops.
Build a new
GIMPLE_ASSIGNtuple and append it to the end of*SEQ_P.
DST/SRC are the destination and source respectively. You can
pass ungimplified trees in DST or SRC, in which
case they will be converted to a gimple operand if necessary.
This function returns the newly created GIMPLE_ASSIGN tuple.
This function is similar to
gimple_build_assign, but is used to build aGIMPLE_ASSIGNstatement when the operands of the right-hand side of the assignment are already split into different operands.The left-hand side is an lvalue passed in lhs. Subcode is the
tree_codefor the right-hand side of the assignment. Op1 and op2 are the operands. If op2 is null, subcode must be atree_codefor a unary expression.
Return the code of the expression computed on the
RHSof assignment statementG.
Return the gimple rhs class of the code for the expression computed on the rhs of assignment statement
G. This will never returnGIMPLE_INVALID_RHS.
Return a pointer to the
LHSof assignment statementG.
Return the first operand on the
RHSof assignment statementG.
Return the address of the first operand on the
RHSof assignment statementG.
Return the second operand on the
RHSof assignment statementG.
Return the address of the second operand on the
RHSof assignment statementG.
Set
LHSto be theLHSoperand of assignment statementG.
Set
RHSto be the first operand on theRHSof assignment statementG.
Return the second operand on the
RHSof assignment statementG.
Return a pointer to the second operand on the
RHSof assignment statementG.
Set
RHSto be the second operand on theRHSof assignment statementG.
Return true if
Sis an type-cast assignment.
GIMPLE_BINDBuild a
GIMPLE_BINDstatement with a list of variables inVARSand a body of statements in sequenceBODY.
Return the variables declared in the
GIMPLE_BINDstatementG.
Set
VARSto be the set of variables declared in theGIMPLE_BINDstatementG.
Append
VARSto the set of variables declared in theGIMPLE_BINDstatementG.
Return the GIMPLE sequence contained in the
GIMPLE_BINDstatementG.
Set
SEQto be sequence contained in theGIMPLE_BINDstatementG.
Append a statement to the end of a
GIMPLE_BIND's body.
Append a sequence of statements to the end of a
GIMPLE_BIND's body.
Return the
TREE_BLOCKnode associated withGIMPLE_BINDstatementG. This is analogous to theBIND_EXPR_BLOCKfield in trees.
Set
BLOCKto be theTREE_BLOCKnode associated withGIMPLE_BINDstatementG.
GIMPLE_CALLBuild a
GIMPLE_CALLstatement to functionFN. The argumentFNmust be either aFUNCTION_DECLor a gimple call address as determined byis_gimple_call_addr.NARGSare the number of arguments. The rest of the arguments follow the argumentNARGS, and must be trees that are valid as rvalues in gimple (i.e., each operand is validated withis_gimple_operand).
Build a
GIMPLE_CALLfrom aCALL_EXPRnode. The arguments and the function are taken from the expression directly. This routine assumes thatcall_expris already in GIMPLE form. That is, its operands are GIMPLE values and the function call needs no further simplification. All the call flags incall_exprare copied over to the newGIMPLE_CALL.
VEC(tree, heap) *args)Identical to
gimple_build_callbut the arguments are stored in aVEC().
Return a pointer to the
LHSof call statementG.
Set
LHSto be theLHSoperand of call statementG.
Return the tree node representing the function called by call statement
G.
Set
FNto be the function called by call statementG. This has to be a gimple value specifying the address of the called function.
If a given
GIMPLE_CALL's callee is aFUNCTION_DECL, return it. Otherwise returnNULL. This function is analogous toget_callee_fndeclinGENERIC.
Set the called function to
FNDECL.
Return the type returned by call statement
G.
Set
CHAINto be the static chain for call statementG.
Return the number of arguments used by call statement
G.
Return the argument at position
INDEXfor call statementG. The first argument is 0.
Return a pointer to the argument at position
INDEXfor call statementG.
Set
ARGto be the argument at positionINDEXfor call statementG.
Mark call statement
Sas being a tail call (i.e., a call just before the exit of a function). These calls are candidate for tail call optimization.
Return true if
GIMPLE_CALLSis marked as a tail call.
Mark
GIMPLE_CALLSas being uninlinable.
Return true if
GIMPLE_CALLScannot be inlined.
Build a
GIMPLE_CALLidentical toSTMTbut skipping the arguments in the positions marked by the setARGS_TO_SKIP.
GIMPLE_CATCHBuild a
GIMPLE_CATCHstatement.TYPESare the tree types this catch handles.HANDLERis a sequence of statements with the code for the handler.
Return the types handled by
GIMPLE_CATCHstatementG.
Return a pointer to the types handled by
GIMPLE_CATCHstatementG.
Return the GIMPLE sequence representing the body of the handler of
GIMPLE_CATCHstatementG.
Set
Tto be the set of types handled byGIMPLE_CATCHG.
Set
HANDLERto be the body ofGIMPLE_CATCHG.
GIMPLE_CHANGE_DYNAMIC_TYPEBuild a
GIMPLE_CHANGE_DYNAMIC_TYPEstatement.TYPEis the new type for the locationPTR.
Return the new type set by
GIMPLE_CHANGE_DYNAMIC_TYPEstatementG.
Return a pointer to the new type set by
GIMPLE_CHANGE_DYNAMIC_TYPEstatementG.
Set
NEW_TYPEto be the type returned byGIMPLE_CHANGE_DYNAMIC_TYPEstatementG.
Return the location affected by
GIMPLE_CHANGE_DYNAMIC_TYPEstatementG.
Return a pointer to the location affected by
GIMPLE_CHANGE_DYNAMIC_TYPEstatementG.
Set
PTRto be the location affected byGIMPLE_CHANGE_DYNAMIC_TYPEstatementG.
GIMPLE_CONDBuild a
GIMPLE_CONDstatement.AGIMPLE_CONDstatement comparesLHSandRHSand if the condition inPRED_CODEis true, jump to the label int_label, otherwise jump to the label inf_label.PRED_CODEare relational operator tree codes likeEQ_EXPR,LT_EXPR,LE_EXPR,NE_EXPR, etc.
Build a
GIMPLE_CONDstatement from the conditional expression treeCOND.T_LABELandF_LABELare as ingimple_build_cond.
Return the code of the predicate computed by conditional statement
G.
Set
CODEto be the predicate code for the conditional statementG.
Return the
LHSof the predicate computed by conditional statementG.
Set
LHSto be theLHSoperand of the predicate computed by conditional statementG.
Return the
RHSoperand of the predicate computed by conditionalG.
Set
RHSto be theRHSoperand of the predicate computed by conditional statementG.
Return the label used by conditional statement
Gwhen its predicate evaluates to true.
Set
LABELto be the label used by conditional statementGwhen its predicate evaluates to true.
Set
LABELto be the label used by conditional statementGwhen its predicate evaluates to false.
Return the label used by conditional statement
Gwhen its predicate evaluates to false.
Set the conditional
COND_STMTto be of the form 'if (1 == 0)'.
Set the conditional
COND_STMTto be of the form 'if (1 == 1)'.
GIMPLE_EH_FILTERBuild a
GIMPLE_EH_FILTERstatement.TYPESare the filter's types.FAILUREis a sequence with the filter's failure action.
Return the types handled by
GIMPLE_EH_FILTERstatementG.
Return a pointer to the types handled by
GIMPLE_EH_FILTERstatementG.
Return the sequence of statement to execute when
GIMPLE_EH_FILTERstatement fails.
Set
TYPESto be the set of types handled byGIMPLE_EH_FILTERG.
Set
FAILUREto be the sequence of statements to execute on failure forGIMPLE_EH_FILTERG.
Return the
EH_FILTER_MUST_NOT_THROWflag.
Set the
EH_FILTER_MUST_NOT_THROWflag.
GIMPLE_LABELBuild a
GIMPLE_LABELstatement with corresponding to the tree label,LABEL.
Return the
LABEL_DECLnode used byGIMPLE_LABELstatementG.
Set
LABELto be theLABEL_DECLnode used byGIMPLE_LABELstatementG.
Build a
GIMPLE_GOTOstatement to labelDEST.
Return the destination of the unconditional jump
G.
Set
DESTto be the destination of the unconditional jumpG.
GIMPLE_NOPGIMPLE_OMP_ATOMIC_LOADBuild a
GIMPLE_OMP_ATOMIC_LOADstatement.LHSis the left-hand side of the assignment.RHSis the right-hand side of the assignment.
Set the
LHSof an atomic load.
Set the
RHSof an atomic set.
GIMPLE_OMP_ATOMIC_STOREBuild a
GIMPLE_OMP_ATOMIC_STOREstatement.VALis the value to be stored.
Set the value being stored in an atomic store.
Return the value being stored in an atomic store.
GIMPLE_OMP_CONTINUEBuild a
GIMPLE_OMP_CONTINUEstatement.CONTROL_DEFis the definition of the control variable.CONTROL_USEis the use of the control variable.
Return the definition of the control variable on a
GIMPLE_OMP_CONTINUEinS.
Same as above, but return the pointer.
Set the control variable definition for a
GIMPLE_OMP_CONTINUEstatement inS.
Return the use of the control variable on a
GIMPLE_OMP_CONTINUEinS.
Same as above, but return the pointer.
Set the control variable use for a
GIMPLE_OMP_CONTINUEstatement inS.
GIMPLE_OMP_CRITICALBuild a
GIMPLE_OMP_CRITICALstatement.BODYis the sequence of statements for which only one thread can execute.NAMEis an optional identifier for this critical block.
Return the name associated with
OMP_CRITICALstatementG.
Return a pointer to the name associated with
OMPcritical statementG.
Set
NAMEto be the name associated withOMPcritical statementG.
GIMPLE_OMP_FORBuild a
GIMPLE_OMP_FORstatement.BODYis sequence of statements inside the for loop.CLAUSES, are any of theOMPloop construct's clauses: private, firstprivate, lastprivate, reductions, ordered, schedule, and nowait.PRE_BODYis the sequence of statements that are loop invariant.INDEXis the index variable.INITIALis the initial value ofINDEX.FINALis final value ofINDEX. OMP_FOR_COND is the predicate used to compareINDEXandFINAL.INCRis the increment expression.
Return the clauses associated with
OMP_FORG.
Set
CLAUSESto be the list of clauses associated withOMP_FORG.
Return a pointer to the index variable for
OMP_FORG.
Set
INDEXto be the index variable forOMP_FORG.
Return a pointer to the initial value for
OMP_FORG.
Set
INITIALto be the initial value forOMP_FORG.
turn a pointer to the final value for
OMP_FORG.
Set
FINALto be the final value forOMP_FORG.
Return a pointer to the increment value for
OMP_FORG.
Set
INCRto be the increment value forOMP_FORG.
Return the sequence of statements to execute before the
OMP_FORstatementGstarts.
Set
PRE_BODYto be the sequence of statements to execute before theOMP_FORstatementGstarts.
Set
CONDto be the condition code forOMP_FORG.
Return the condition code associated with
OMP_FORG.
GIMPLE_OMP_MASTERBuild a
GIMPLE_OMP_MASTERstatement.BODYis the sequence of statements to be executed by just the master.
GIMPLE_OMP_ORDEREDBuild a
GIMPLE_OMP_ORDEREDstatement.
BODY is the sequence of statements inside a loop that will
executed in sequence.
GIMPLE_OMP_PARALLELBuild a
GIMPLE_OMP_PARALLELstatement.
BODY is sequence of statements which are executed in parallel.
CLAUSES, are the OMP parallel construct's clauses. CHILD_FN is
the function created for the parallel threads to execute.
DATA_ARG are the shared data argument(s).
Return true if
OMPparallel statementGhas theGF_OMP_PARALLEL_COMBINEDflag set.
Set the
GF_OMP_PARALLEL_COMBINEDfield inOMPparallel statementG.
Set
BODYto be the body for theOMPstatementG.
Return the clauses associated with
OMP_PARALLELG.
Return a pointer to the clauses associated with
OMP_PARALLELG.
Set
CLAUSESto be the list of clauses associated withOMP_PARALLELG.
Return the child function used to hold the body of
OMP_PARALLELG.
Return a pointer to the child function used to hold the body of
OMP_PARALLELG.
Set
CHILD_FNto be the child function forOMP_PARALLELG.
Return the artificial argument used to send variables and values from the parent to the children threads in
OMP_PARALLELG.
Return a pointer to the data argument for
OMP_PARALLELG.
Set
DATA_ARGto be the data argument forOMP_PARALLELG.
Returns true when the gimple statement
STMTis any of the OpenMP types.
GIMPLE_OMP_RETURNBuild a
GIMPLE_OMP_RETURNstatement.WAIT_Pis true if this is a non-waiting return.
Set the nowait flag on
GIMPLE_OMP_RETURNstatementS.
Return true if
OMPreturn statementGhas theGF_OMP_RETURN_NOWAITflag set.
GIMPLE_OMP_SECTIONBuild a
GIMPLE_OMP_SECTIONstatement for a sections statement.
BODY is the sequence of statements in the section.
Return true if
OMPsection statementGhas theGF_OMP_SECTION_LASTflag set.
Set the
GF_OMP_SECTION_LASTflag onG.
GIMPLE_OMP_SECTIONSBuild a
GIMPLE_OMP_SECTIONSstatement.BODYis a sequence of section statements.CLAUSESare any of theOMPsections construct's clauses: private, firstprivate, lastprivate, reduction, and nowait.
Build a
GIMPLE_OMP_SECTIONS_SWITCHstatement.
Return the control variable associated with the
GIMPLE_OMP_SECTIONSinG.
Return a pointer to the clauses associated with the
GIMPLE_OMP_SECTIONSinG.
Set
CONTROLto be the set of clauses associated with theGIMPLE_OMP_SECTIONSinG.
Return the clauses associated with
OMP_SECTIONSG.
Return a pointer to the clauses associated with
OMP_SECTIONSG.
Set
CLAUSESto be the set of clauses associated withOMP_SECTIONSG.
GIMPLE_OMP_SINGLEBuild a
GIMPLE_OMP_SINGLEstatement.BODYis the sequence of statements that will be executed once.CLAUSESare any of theOMPsingle construct's clauses: private, firstprivate, copyprivate, nowait.
Return the clauses associated with
OMP_SINGLEG.
Return a pointer to the clauses associated with
OMP_SINGLEG.
Set
CLAUSESto be the clauses associated withOMP_SINGLEG.
GIMPLE_PHIBuild a
PHInode with len argument slots for variable var.
Return the maximum number of arguments supported by
GIMPLE_PHIG.
Return the number of arguments in
GIMPLE_PHIG. This must always be exactly the number of incoming edges for the basic block holdingG.
Return a pointer to the
SSAname created byGIMPLE_PHIG.
Set
RESULTto be theSSAname created byGIMPLE_PHIG.
Return the
PHIargument corresponding to incoming edgeINDEXforGIMPLE_PHIG.
Set
PHIARGto be the argument corresponding to incoming edgeINDEXforGIMPLE_PHIG.
GIMPLE_RESXBuild a
GIMPLE_RESXstatement which is a statement. This statement is a placeholder for _Unwind_Resume before we know if a function call or a branch is needed.REGIONis the exception region from which control is flowing.
Set
REGIONto be the region number forGIMPLE_RESXG.
GIMPLE_RETURNBuild a
GIMPLE_RETURNstatement whose return value is retval.
Return the return value for
GIMPLE_RETURNG.
Set
RETVALto be the return value forGIMPLE_RETURNG.
GIMPLE_SWITCHBuild a
GIMPLE_SWITCHstatement.NLABELSare the number of labels excluding the default label. The default label is passed inDEFAULT_LABEL. The rest of the arguments are trees representing the labels. Each label is a tree of codeCASE_LABEL_EXPR.
VEC(tree,heap) *args)This function is an alternate way of building
GIMPLE_SWITCHstatements.INDEXandDEFAULT_LABELare as in gimple_build_switch.ARGSis a vector ofCASE_LABEL_EXPRtrees that contain the labels.
Return the number of labels associated with the switch statement
G.
Set
NLABELSto be the number of labels for the switch statementG.
Return the index variable used by the switch statement
G.
Set
INDEXto be the index variable for switch statementG.
Return the label numbered
INDEX. The default label is 0, followed by any labels in a switch statement.
Set the label number
INDEXtoLABEL. 0 is always the default label.
Return the default label for a switch statement.
Set the default label for a switch statement.
GIMPLE_TRYBuild a
GIMPLE_TRYstatement.EVALis a sequence with the expression to evaluate.CLEANUPis a sequence of statements to run at clean-up time.KINDis the enumeration valueGIMPLE_TRY_CATCHif this statement denotes a try/catch construct orGIMPLE_TRY_FINALLYif this statement denotes a try/finally construct.
Return the kind of try block represented by
GIMPLE_TRYG. This is eitherGIMPLE_TRY_CATCHorGIMPLE_TRY_FINALLY.
Return the
GIMPLE_TRY_CATCH_IS_CLEANUPflag.
Return the sequence of statements used as the body for
GIMPLE_TRYG.
Return the sequence of statements used as the cleanup body for
GIMPLE_TRYG.
Set the
GIMPLE_TRY_CATCH_IS_CLEANUPflag.
Set
EVALto be the sequence of statements to use as the body forGIMPLE_TRYG.
Set
CLEANUPto be the sequence of statements to use as the cleanup body forGIMPLE_TRYG.
GIMPLE_WITH_CLEANUP_EXPRBuild a
GIMPLE_WITH_CLEANUP_EXPRstatement.CLEANUPis the clean-up expression.
Return the cleanup sequence for cleanup statement
G.
Set
CLEANUPto be the cleanup sequence forG.
Return the
CLEANUP_EH_ONLYflag for aWCEtuple.
Set the
CLEANUP_EH_ONLYflag for aWCEtuple.
GIMPLE sequences are the tuple equivalent of STATEMENT_LIST's
used in GENERIC. They are used to chain statements together, and
when used in conjunction with sequence iterators, provide a
framework for iterating through statements.
GIMPLE sequences are of type struct gimple_sequence, but are more
commonly passed by reference to functions dealing with sequences.
The type for a sequence pointer is gimple_seq which is the same
as struct gimple_sequence *. When declaring a local sequence,
you can define a local variable of type struct gimple_sequence.
When declaring a sequence allocated on the garbage collected
heap, use the function gimple_seq_alloc documented below.
There are convenience functions for iterating through sequences in the section entitled Sequence Iterators.
Below is a list of functions to manipulate and query sequences.
Link a gimple statement to the end of the sequence *
SEQifGis notNULL. If *SEQisNULL, allocate a sequence before linking.
Append sequence
SRCto the end of sequence *DESTifSRCis notNULL. If *DESTisNULL, allocate a new sequence before appending.
Perform a deep copy of sequence
SRCand return the result.
Reverse the order of the statements in the sequence
SEQ. ReturnSEQ.
Set the last statement in sequence
Sto the statement inLAST.
Set the first statement in sequence
Sto the statement inFIRST.
Allocate a new sequence in the garbage collected store and return it.
Copy the sequence
SRCinto the sequenceDEST.
Sets the sequence of statements in
BBtoSEQ.
Determine whether
SEQcontains exactly one statement.
Sequence iterators are convenience constructs for iterating
through statements in a sequence. Given a sequence SEQ, here is
a typical use of gimple sequence iterators:
gimple_stmt_iterator gsi;
for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple g = gsi_stmt (gsi);
/* Do something with gimple statement G. */
}
Backward iterations are possible:
for (gsi = gsi_last (seq); !gsi_end_p (gsi); gsi_prev (&gsi))
Forward and backward iterations on basic blocks are possible with
gsi_start_bb and gsi_last_bb.
In the documentation below we sometimes refer to enum
gsi_iterator_update. The valid options for this enumeration are:
GSI_NEW_STMT
Only valid when a single statement is added. Move the iterator to it.
GSI_SAME_STMT
Leave the iterator at the same statement.
GSI_CONTINUE_LINKING
Move iterator to whatever position is suitable for linking other
statements in the same direction.
Below is a list of the functions used to manipulate and use statement iterators.
Return a new iterator pointing to the sequence
SEQ's first statement. IfSEQis empty, the iterator's basic block isNULL. Usegsi_start_bbinstead when the iterator needs to always have the correct basic block set.
Return a new iterator pointing to the first statement in basic block
BB.
Return a new iterator initially pointing to the last statement of sequence
SEQ. IfSEQis empty, the iterator's basic block isNULL. Usegsi_last_bbinstead when the iterator needs to always have the correct basic block set.
Return a new iterator pointing to the last statement in basic block
BB.
Return
TRUEif we're one statement before the end ofI.
Advance the iterator to the next gimple statement.
Advance the iterator to the previous gimple statement.
Return a block statement iterator that points to the first non-label statement in block
BB.
Return a pointer to the current stmt.
Return the basic block associated with this iterator.
Return the sequence associated with this iterator.
Remove the current stmt from the sequence. The iterator is updated to point to the next statement. When
REMOVE_EH_INFOis true we remove the statement pointed to by iteratorIfrom theEHtables. Otherwise we do not modify theEHtables. Generally,REMOVE_EH_INFOshould be true when the statement is going to be removed from theILand not reinserted elsewhere.
Links the sequence of statements
SEQbefore the statement pointed by iteratorI.MODEindicates what to do with the iterator after insertion (seeenum gsi_iterator_updateabove).
Links statement
Gbefore the statement pointed-to by iteratorI. Updates iteratorIaccording toMODE.
Links sequence
SEQafter the statement pointed-to by iteratorI.MODEis as ingsi_insert_after.
Links statement
Gafter the statement pointed-to by iteratorI.MODEis as ingsi_insert_after.
Move all statements in the sequence after
Ito a new sequence. Return this new sequence.
Move all statements in the sequence before
Ito a new sequence. Return this new sequence.
Replace the statement pointed-to by
ItoSTMT. IfUPDATE_EH_INFOis true, the exception handling information of the original statement is moved to the new statement.
Insert statement
STMTbefore the statement pointed-to by iteratorI, updateSTMT's basic block and scan it for new operands.MODEspecifies how to update iteratorIafter insertion (see enumgsi_iterator_update).
Like
gsi_insert_before, but for all the statements inSEQ.
Insert statement
STMTafter the statement pointed-to by iteratorI, updateSTMT's basic block and scan it for new operands.MODEspecifies how to update iteratorIafter insertion (see enumgsi_iterator_update).
Like
gsi_insert_after, but for all the statements inSEQ.
Move the statement at
FROMso it comes right after the statement atTO.
Move the statement at
FROMso it comes right before the statement atTO.
Move the statement at
FROMto the end of basic blockBB.
Add
STMTto the pending list of edgeE. No actual insertion is made until a call togsi_commit_edge_inserts() is made.
Add the sequence of statements in
SEQto the pending list of edgeE. No actual insertion is made until a call togsi_commit_edge_inserts() is made.
Similar to
gsi_insert_on_edge+gsi_commit_edge_inserts. If a new block has to be created, it is returned.
Commit insertions pending at edge
E. If a new block is created, setNEW_BBto this block, otherwise set it toNULL.
This routine will commit all pending edge insertions, creating any new basic blocks which are necessary.
The first step in adding a new GIMPLE statement code, is
modifying the file gimple.def, which contains all the GIMPLE
codes. Then you must add a corresponding structure, and an entry
in union gimple_statement_d, both of which are located in
gimple.h. This in turn, will require you to add a corresponding
GTY tag in gsstruct.def, and code to handle this tag in
gss_for_code which is located in gimple.c.
In order for the garbage collector to know the size of the
structure you created in gimple.h, you need to add a case to
handle your new GIMPLE statement in gimple_size which is located
in gimple.c.
You will probably want to create a function to build the new
gimple statement in gimple.c. The function should be called
gimple_build_<NEW_TUPLE_NAME>, and should return the new tuple
of type gimple.
If your new statement requires accessors for any members or
operands it may have, put simple inline accessors in
gimple.h and any non-trivial accessors in gimple.c with a
corresponding prototype in gimple.h.
There are two functions available for walking statements and
sequences: walk_gimple_stmt and walk_gimple_seq,
accordingly, and a third function for walking the operands in a
statement: walk_gimple_op.
This function is used to walk the current statement in
GSI, optionally using traversal state stored inWI. IfWIisNULL, no state is kept during the traversal.The callback
CALLBACK_STMTis called. IfCALLBACK_STMTreturns true, it means that the callback function has handled all the operands of the statement and it is not necessary to walk its operands.If
CALLBACK_STMTisNULLor it returns false,CALLBACK_OPis called on each operand of the statement viawalk_gimple_op. Ifwalk_gimple_opreturns non-NULLfor any operand, the remaining operands are not scanned.The return value is that returned by the last call to
walk_gimple_op, orNULL_TREEif noCALLBACK_OPis specified.
Use this function to walk the operands of statement
STMT. Every operand is walked viawalk_treewith optional state information inWI.
CALLBACK_OPis called on each operand ofSTMTviawalk_tree. Additional parameters towalk_treemust be stored inWI. For each operandOP,walk_treeis called as:walk_tree (&OP,CALLBACK_OP,WI,WI-PSET)If
CALLBACK_OPreturns non-NULLfor an operand, the remaining operands are not scanned. The return value is that returned by the last call towalk_tree, orNULL_TREEif noCALLBACK_OPis specified.
This function walks all the statements in the sequence
SEQcallingwalk_gimple_stmton each one.WIis as inwalk_gimple_stmt. Ifwalk_gimple_stmtreturns non-NULL, the walk is stopped and the value returned. Otherwise, all the statements are walked andNULL_TREEreturned.