Because many SUIF passes focus on analyzing and optimizing Fortran code,
a high-level representation of array references is crucial. SUIF
provides array
instructions which retain all of the high-level
information in combination with other fields needed to generate code for
the address computations. The in_array
class is used to hold
these array instructions.
Array instructions include a number of fields. First, a pointer to the
base of the array is specified in an operand field that can be accessed
with the base_op
and set_base_op
methods. If the array
elements are structures, a constant offset within the selected element
may be included. This optional integer offset can be accessed using the
offset
and set_offset
methods. The element size is needed
to generate low-level code for the array address calculation. The
elem_size
method returns the element size in bits. The
set_elem_size
method may be used to change the element size.
Because Fortran arrays do not always begin with index zero, an optional
operand, which is referenced using the offset_op
and
set_offset_op
methods, is provided to specify an offset. Since
there is a single offset operand, the offsets for all of the dimensions
must be combined into a single value. The arrays are stored in
row-major form, so the offset for the first dimension is multiplied by
the size of the remaining dimensions, etc. If the offset operand is
provided, it must have an integer type.
Array instructions can treat arrays of arrays as multidimensional
arrays, even though the type system does not support that directly.
Each array instruction includes a field to specify the number of
dimensions in the array. This field may be accessed with the
dims
and set_dims
methods. The indexes for the array
reference are stored in an array of source operands, one for each
dimension. These index operands can be accessed using the index
and set_index
methods. The dimensions are numbered beginning
with zero. Similarly, the number of elements in each dimension are
stored in another array of source operands, which can be accessed with
the bound
and set_bound
methods.
The result type of an array instruction must be a pointer. However, it
need not be a pointer to the element type. If the elements are
structures, the result type may be a pointer to one of the structure
fields. SUIF does not actually require that the result type match
anything within the array element type, although that is highly
recommended. The elem_type
method can be used to determine the
actual type of the element being addressed.
The types of the array instruction operands must follow some conventions. The index and bound operands must all have integer types. The base operand must be a pointer to an array. If the array instruction has multiple dimensions, the base must point to a nested array (an array of arrays of arrays...) with the same depth as the number of dimensions. For each dimension, if the bound operand is a constant, it must match the number of elements specified in the corresponding array type. (If the lower and upper bounds in the array type are not both constant, then the bound operand may have any value.) The bound operand for the first dimension is optional and may be null. Finally, the element size must match the size of the elements in the array type.