aboutsummaryrefslogtreecommitdiff
path: root/gcc/stor-layout.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1998-05-18 06:21:14 -0700
committerRichard Henderson <rth@gcc.gnu.org>1998-05-18 06:21:14 -0700
commitead1705900f4e5c6e06407208b928d83b4646320 (patch)
tree52f254790542ea9c24b53b11b490678708eeaa15 /gcc/stor-layout.c
parent6d73fddc3f93058d8f3534a3b888779a134c484e (diff)
downloadgcc-ead1705900f4e5c6e06407208b928d83b4646320.zip
gcc-ead1705900f4e5c6e06407208b928d83b4646320.tar.gz
gcc-ead1705900f4e5c6e06407208b928d83b4646320.tar.bz2
tree.h (TYPE_SIZE_UNIT): New.
* tree.h (TYPE_SIZE_UNIT): New. (struct tree_type): Add size_unit member. * stor-layout.c (layout_type): Initialize it. * expr.c (get_inner_reference) [ARRAY_REF]: Use it. * tree.c (size_in_bytes, int_size_in_bytes): Likewise. From-SVN: r19853
Diffstat (limited to 'gcc/stor-layout.c')
-rw-r--r--gcc/stor-layout.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index c9fee7b..77561c9 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -720,11 +720,13 @@ layout_type (type)
TYPE_MODE (type) = smallest_mode_for_size (TYPE_PRECISION (type),
MODE_INT);
TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)), 0L);
+ TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
break;
case REAL_TYPE:
TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0);
TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)), 0L);
+ TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
break;
case COMPLEX_TYPE:
@@ -735,29 +737,34 @@ layout_type (type)
? MODE_COMPLEX_INT : MODE_COMPLEX_FLOAT),
0);
TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)), 0L);
+ TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
break;
case VOID_TYPE:
TYPE_SIZE (type) = size_zero_node;
+ TYPE_SIZE_UNIT (type) = size_zero_node;
TYPE_ALIGN (type) = 1;
TYPE_MODE (type) = VOIDmode;
break;
case OFFSET_TYPE:
TYPE_SIZE (type) = bitsize_int (POINTER_SIZE, 0L);
+ TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT);
TYPE_MODE (type) = ptr_mode;
break;
case FUNCTION_TYPE:
case METHOD_TYPE:
TYPE_MODE (type) = mode_for_size (2 * POINTER_SIZE, MODE_INT, 0);
- TYPE_SIZE (type) = size_int (2 * POINTER_SIZE);
+ TYPE_SIZE (type) = bitsize_int (2 * POINTER_SIZE, 0);
+ TYPE_SIZE_UNIT (type) = size_int ((2 * POINTER_SIZE) / BITS_PER_UNIT);
break;
case POINTER_TYPE:
case REFERENCE_TYPE:
TYPE_MODE (type) = ptr_mode;
TYPE_SIZE (type) = bitsize_int (POINTER_SIZE, 0L);
+ TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT);
TREE_UNSIGNED (type) = 1;
TYPE_PRECISION (type) = POINTER_SIZE;
break;
@@ -810,6 +817,17 @@ layout_type (type)
TYPE_SIZE (type) = size_binop (MULT_EXPR, TYPE_SIZE (element),
length);
+
+ /* If we know the size of the element, calculate the total
+ size directly, rather than do some division thing below.
+ This optimization helps Fortran assumed-size arrays
+ (where the size of the array is determined at runtime)
+ substantially. */
+ if (TYPE_SIZE_UNIT (element) != 0)
+ {
+ TYPE_SIZE_UNIT (type)
+ = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (element), length);
+ }
}
/* Now round the alignment and size,
@@ -824,8 +842,15 @@ layout_type (type)
#ifdef ROUND_TYPE_SIZE
if (TYPE_SIZE (type) != 0)
- TYPE_SIZE (type)
- = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type));
+ {
+ tree tmp;
+ tmp = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type));
+ /* If the rounding changed the size of the type, remove any
+ pre-calculated TYPE_SIZE_UNIT. */
+ if (simple_cst_equal (TYPE_SIZE (type), tmp) != 1)
+ TYPE_SIZE_UNIT (type) = NULL;
+ TYPE_SIZE (type) = tmp;
+ }
#endif
TYPE_MODE (type) = BLKmode;
@@ -983,6 +1008,7 @@ layout_type (type)
else
TYPE_MODE (type) = mode_for_size (alignment, MODE_INT, 1);
TYPE_SIZE (type) = bitsize_int (rounded_size, 0L);
+ TYPE_SIZE_UNIT (type) = size_int (rounded_size / BITS_PER_UNIT);
TYPE_ALIGN (type) = alignment;
TYPE_PRECISION (type) = size_in_bits;
}
@@ -1015,6 +1041,19 @@ layout_type (type)
if (TYPE_SIZE (type) != 0 && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
TYPE_SIZE (type) = variable_size (TYPE_SIZE (type));
+ /* If we failed to find a simple way to calculate the unit size
+ of the type above, find it by division. */
+ if (TYPE_SIZE_UNIT (type) == 0 && TYPE_SIZE (type) != 0)
+ {
+ TYPE_SIZE_UNIT (type) = size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (type),
+ size_int (BITS_PER_UNIT));
+ }
+
+ /* Once again evaluate only once, either now or as soon as safe. */
+ if (TYPE_SIZE_UNIT (type) != 0
+ && TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
+ TYPE_SIZE_UNIT (type) = variable_size (TYPE_SIZE_UNIT (type));
+
/* Also layout any other variants of the type. */
if (TYPE_NEXT_VARIANT (type)
|| type != TYPE_MAIN_VARIANT (type))
@@ -1022,6 +1061,7 @@ layout_type (type)
tree variant;
/* Record layout info of this variant. */
tree size = TYPE_SIZE (type);
+ tree size_unit = TYPE_SIZE_UNIT (type);
int align = TYPE_ALIGN (type);
enum machine_mode mode = TYPE_MODE (type);
@@ -1031,6 +1071,7 @@ layout_type (type)
variant = TYPE_NEXT_VARIANT (variant))
{
TYPE_SIZE (variant) = size;
+ TYPE_SIZE_UNIT (variant) = size_unit;
TYPE_ALIGN (variant) = align;
TYPE_MODE (variant) = mode;
}