gccint: Tuple representation

1 
1 12.1 Tuple representation
1 =========================
1 
1 GIMPLE instructions are tuples of variable size divided in two groups: a
1 header describing the instruction and its locations, and a variable
1 length body with all the operands.  Tuples are organized into a
1 hierarchy with 3 main classes of tuples.
1 
1 12.1.1 'gimple' (gsbase)
1 ------------------------
1 
1 This is the root of the hierarchy, it holds basic information needed by
1 most GIMPLE statements.  There are some fields that may not be relevant
1 to every GIMPLE statement, but those were moved into the base structure
1 to take advantage of holes left by other fields (thus making the
1 structure more compact).  The structure takes 4 words (32 bytes) on 64
1 bit hosts:
1 
1 Field                   Size (bits)
1 'code'                  8
1 'subcode'               16
1 'no_warning'            1
1 'visited'               1
1 'nontemporal_move'      1
1 'plf'                   2
1 'modified'              1
1 'has_volatile_ops'      1
1 'references_memory_p'   1
1 'uid'                   32
1 'location'              32
1 'num_ops'               32
1 'bb'                    64
1 'block'                 63
1 Total size              32 bytes
1 
1    * 'code' Main identifier for a GIMPLE instruction.
1 
1    * 'subcode' Used to distinguish different variants of the same basic
1      instruction or provide flags applicable to a given code.  The
1      'subcode' flags field has different uses depending on the code of
1      the instruction, but mostly it distinguishes instructions of the
1      same family.  The most prominent use of this field is in
1      assignments, where subcode indicates the operation done on the RHS
1      of the assignment.  For example, a = b + c is encoded as
1      'GIMPLE_ASSIGN <PLUS_EXPR, a, b, c>'.
1 
1    * 'no_warning' Bitflag to indicate whether a warning has already been
1      issued on this statement.
1 
1    * 'visited' General purpose "visited" marker.  Set and cleared by
1      each pass when needed.
1 
1    * 'nontemporal_move' Bitflag used in assignments that represent
1      non-temporal moves.  Although this bitflag is only used in
1      assignments, it was moved into the base to take advantage of the
1      bit holes left by the previous fields.
1 
1    * 'plf' Pass Local Flags.  This 2-bit mask can be used as general
1      purpose markers by any pass.  Passes are responsible for clearing
1      and setting these two flags accordingly.
1 
1    * 'modified' Bitflag to indicate whether the statement has been
1      modified.  Used mainly by the operand scanner to determine when to
1      re-scan a statement for operands.
1 
1    * 'has_volatile_ops' Bitflag to indicate whether this statement
1      contains operands that have been marked volatile.
1 
1    * 'references_memory_p' Bitflag to indicate whether this statement
1      contains memory references (i.e., its operands are either global
1      variables, or pointer dereferences or anything that must reside in
1      memory).
1 
1    * 'uid' This is an unsigned integer used by passes that want to
1      assign IDs to every statement.  These IDs must be assigned and used
1      by each pass.
1 
1    * 'location' This is a 'location_t' identifier to specify source code
1      location for this statement.  It is inherited from the front end.
1 
1    * 'num_ops' Number of operands that this statement has.  This
1      specifies the size of the operand vector embedded in the tuple.
1      Only used in some tuples, but it is declared in the base tuple to
1      take advantage of the 32-bit hole left by the previous fields.
1 
1    * 'bb' Basic block holding the instruction.
1 
1    * 'block' Lexical block holding this statement.  Also used for debug
1      information generation.
1 
1 12.1.2 'gimple_statement_with_ops'
1 ----------------------------------
1 
1 This tuple is actually split in two: 'gimple_statement_with_ops_base'
1 and 'gimple_statement_with_ops'.  This is needed to accommodate the way
1 the operand vector is allocated.  The operand vector is defined to be an
1 array of 1 element.  So, to allocate a dynamic number of operands, the
1 memory allocator ('gimple_alloc') simply allocates enough memory to hold
1 the structure itself plus 'N - 1' operands which run "off the end" of
1 the structure.  For example, to allocate space for a tuple with 3
1 operands, 'gimple_alloc' reserves 'sizeof (struct
1 gimple_statement_with_ops) + 2 * sizeof (tree)' bytes.
1 
1  On the other hand, several fields in this tuple need to be shared with
1 the 'gimple_statement_with_memory_ops' tuple.  So, these common fields
1 are placed in 'gimple_statement_with_ops_base' which is then inherited
1 from the other two tuples.
1 
1 'gsbase'    256
1 'def_ops'   64
1 'use_ops'   64
1 'op'        'num_ops' * 64
1 Total       48 + 8 * 'num_ops' bytes
1 size
1 
1    * 'gsbase' Inherited from 'struct gimple'.
1 
1    * 'def_ops' Array of pointers into the operand array indicating all
1      the slots that contain a variable written-to by the statement.
1      This array is also used for immediate use chaining.  Note that it
1      would be possible to not rely on this array, but the changes
1      required to implement this are pretty invasive.
1 
1    * 'use_ops' Similar to 'def_ops' but for variables read by the
1      statement.
1 
1    * 'op' Array of trees with 'num_ops' slots.
1 
1 12.1.3 'gimple_statement_with_memory_ops'
1 -----------------------------------------
1 
1 This tuple is essentially identical to 'gimple_statement_with_ops',
1 except that it contains 4 additional fields to hold vectors related
1 memory stores and loads.  Similar to the previous case, the structure is
1 split in two to accommodate for the operand vector
1 ('gimple_statement_with_memory_ops_base' and
1 'gimple_statement_with_memory_ops').
1 
1 Field        Size (bits)
1 'gsbase'     256
1 'def_ops'    64
1 'use_ops'    64
1 'vdef_ops'   64
1 'vuse_ops'   64
1 'stores'     64
1 'loads'      64
1 'op'         'num_ops' * 64
1 Total size   80 + 8 * 'num_ops' bytes
1 
1    * 'vdef_ops' Similar to 'def_ops' but for 'VDEF' operators.  There is
1      one entry per memory symbol written by this statement.  This is
1      used to maintain the memory SSA use-def and def-def chains.
1 
1    * 'vuse_ops' Similar to 'use_ops' but for 'VUSE' operators.  There is
1      one entry per memory symbol loaded by this statement.  This is used
1      to maintain the memory SSA use-def chains.
1 
1    * 'stores' Bitset with all the UIDs for the symbols written-to by the
1      statement.  This is different than 'vdef_ops' in that all the
1      affected symbols are mentioned in this set.  If memory partitioning
1      is enabled, the 'vdef_ops' vector will refer to memory partitions.
1      Furthermore, no SSA information is stored in this set.
1 
1    * 'loads' Similar to 'stores', but for memory loads.  (Note that
1      there is some amount of redundancy here, it should be possible to
1      reduce memory utilization further by removing these sets).
1 
1  All the other tuples are defined in terms of these three basic ones.
1 Each tuple will add some fields.
1