/* Backend support for Fortran 95 basic types and derived types.
- Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
- Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software
+ Foundation, Inc.
Contributed by Paul Brook <paul@nowt.org>
and Steven Bosscher <s.bosscher@student.tudelft.nl>
return element;
}
\f
-/* Build an array. This function is called from gfc_sym_type().
+/* Build an array. This function is called from gfc_sym_type().
Actually returns array descriptor type.
Format of array descriptors is as follows:
index ubound;
}
- Translation code should use gfc_conv_descriptor_* rather than accessing
- the descriptor directly. Any changes to the array descriptor type will
- require changes in gfc_conv_descriptor_* and gfc_build_array_initializer.
+ Translation code should use gfc_conv_descriptor_* rather than
+ accessing the descriptor directly. Any changes to the array
+ descriptor type will require changes in gfc_conv_descriptor_* and
+ gfc_build_array_initializer.
- This is represented internally as a RECORD_TYPE. The index nodes are
- gfc_array_index_type and the data node is a pointer to the data. See below
- for the handling of character types.
+ This is represented internally as a RECORD_TYPE. The index nodes
+ are gfc_array_index_type and the data node is a pointer to the
+ data. See below for the handling of character types.
The dtype member is formatted as follows:
rank = dtype & GFC_DTYPE_RANK_MASK // 3 bits
type = (dtype & GFC_DTYPE_TYPE_MASK) >> GFC_DTYPE_TYPE_SHIFT // 3 bits
size = dtype >> GFC_DTYPE_SIZE_SHIFT
- I originally used nested ARRAY_TYPE nodes to represent arrays, but this
- generated poor code for assumed/deferred size arrays. These require
- use of PLACEHOLDER_EXPR/WITH_RECORD_EXPR, which isn't part of the GENERIC
- grammar. Also, there is no way to explicitly set the array stride, so
- all data must be packed(1). I've tried to mark all the functions which
- would require modification with a GCC ARRAYS comment.
+ I originally used nested ARRAY_TYPE nodes to represent arrays, but
+ this generated poor code for assumed/deferred size arrays. These
+ require use of PLACEHOLDER_EXPR/WITH_RECORD_EXPR, which isn't part
+ of the GENERIC grammar. Also, there is no way to explicitly set
+ the array stride, so all data must be packed(1). I've tried to
+ mark all the functions which would require modification with a GCC
+ ARRAYS comment.
- The data component points to the first element in the array.
- The offset field is the position of the origin of the array
- (ie element (0, 0 ...)). This may be outsite the bounds of the array.
+ The data component points to the first element in the array. The
+ offset field is the position of the origin of the array (ie element
+ (0, 0 ...)). This may be outsite the bounds of the array.
An element is accessed by
- data[offset + index0*stride0 + index1*stride1 + index2*stride2]
+ data[offset + index0*stride0 + index1*stride1 + index2*stride2]
This gives good performance as the computation does not involve the
- bounds of the array. For packed arrays, this is optimized further by
- substituting the known strides.
+ bounds of the array. For packed arrays, this is optimized further
+ by substituting the known strides.
- This system has one problem: all array bounds must be withing 2^31 elements
- of the origin (2^63 on 64-bit machines). For example
- integer, dimension (80000:90000, 80000:90000, 2) :: array
- may not work properly on 32-bit machines because 80000*80000 > 2^31, so
- the calculation for stride02 would overflow. This may still work, but
- I haven't checked, and it relies on the overflow doing the right thing.
+ This system has one problem: all array bounds must be within 2^31
+ elements of the origin (2^63 on 64-bit machines). For example
+ integer, dimension (80000:90000, 80000:90000, 2) :: array
+ may not work properly on 32-bit machines because 80000*80000 >
+ 2^31, so the calculation for stride02 would overflow. This may
+ still work, but I haven't checked, and it relies on the overflow
+ doing the right thing.
The way to fix this problem is to access elements as follows:
- data[(index0-lbound0)*stride0 + (index1-lbound1)*stride1]
- Obviously this is much slower. I will make this a compile time option,
- something like -fsmall-array-offsets. Mixing code compiled with and without
- this switch will work.
-
- (1) This can be worked around by modifying the upper bound of the previous
- dimension. This requires extra fields in the descriptor (both real_ubound
- and fake_ubound). In tree.def there is mention of TYPE_SEP, which
- may allow us to do this. However I can't find mention of this anywhere
- else. */
+ data[(index0-lbound0)*stride0 + (index1-lbound1)*stride1]
+ Obviously this is much slower. I will make this a compile time
+ option, something like -fsmall-array-offsets. Mixing code compiled
+ with and without this switch will work.
+
+ (1) This can be worked around by modifying the upper bound of the
+ previous dimension. This requires extra fields in the descriptor
+ (both real_ubound and fake_ubound). */
/* Returns true if the array sym does not require a descriptor. */