Tuple representation#
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 (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) |
|
8 |
|
16 |
|
1 |
|
1 |
|
1 |
|
2 |
|
1 |
|
1 |
|
1 |
|
32 |
|
32 |
|
32 |
|
64 |
|
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. Thesubcode
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 asGIMPLE_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 alocation_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.
|
256 |
|
64 |
|
64 |
|
|
Total size |
48 + 8 * |
gsbase
Inherited fromstruct gimple
.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 todef_ops
but for variables read by the statement.op
Array of trees withnum_ops
slots.
gimple_statement_with_memory_ops#
This 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) |
|
256 |
|
64 |
|
64 |
|
64 |
|
64 |
|
64 |
|
64 |
|
|
Total size |
80 + 8 * |
vdef_ops
Similar todef_ops
but forVDEF
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 touse_ops
but forVUSE
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 thanvdef_ops
in that all the affected symbols are mentioned in this set. If memory partitioning is enabled, thevdef_ops
vector will refer to memory partitions. Furthermore, no SSA information is stored in this set.loads
Similar tostores
, 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.