mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-29 07:14:05 +08:00
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
This commit is contained in:
parent
6d73fddc3f
commit
ead1705900
@ -1,3 +1,11 @@
|
||||
Mon May 18 13:20:23 1998 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* 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.
|
||||
|
||||
Mon May 18 12:07:37 1998 Richard Earnshaw (rearnsha@arm.com)
|
||||
|
||||
* stor-layout.c (layout_record): Fix off-by-one error when checking
|
||||
|
29
gcc/expr.c
29
gcc/expr.c
@ -4374,6 +4374,7 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
|
||||
tree low_bound
|
||||
= domain ? TYPE_MIN_VALUE (domain) : integer_zero_node;
|
||||
tree index_type = TREE_TYPE (index);
|
||||
tree xindex;
|
||||
|
||||
if (TYPE_PRECISION (index_type) != TYPE_PRECISION (sizetype))
|
||||
{
|
||||
@ -4391,21 +4392,27 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
|
||||
index_type = TREE_TYPE (index);
|
||||
}
|
||||
|
||||
index = fold (build (MULT_EXPR, sbitsizetype, index,
|
||||
convert (sbitsizetype,
|
||||
TYPE_SIZE (TREE_TYPE (exp)))));
|
||||
xindex = fold (build (MULT_EXPR, sbitsizetype, index,
|
||||
convert (sbitsizetype,
|
||||
TYPE_SIZE (TREE_TYPE (exp)))));
|
||||
|
||||
if (TREE_CODE (index) == INTEGER_CST
|
||||
&& TREE_INT_CST_HIGH (index) == 0)
|
||||
*pbitpos += TREE_INT_CST_LOW (index);
|
||||
if (TREE_CODE (xindex) == INTEGER_CST
|
||||
&& TREE_INT_CST_HIGH (xindex) == 0)
|
||||
*pbitpos += TREE_INT_CST_LOW (xindex);
|
||||
else
|
||||
{
|
||||
if (contains_placeholder_p (index))
|
||||
index = build (WITH_RECORD_EXPR, sizetype, index, exp);
|
||||
/* Either the bit offset calculated above is not constant, or
|
||||
it overflowed. In either case, redo the multiplication
|
||||
against the size in units. This is especially important
|
||||
in the non-constant case to avoid a division at runtime. */
|
||||
xindex = fold (build (MULT_EXPR, ssizetype, index,
|
||||
convert (ssizetype,
|
||||
TYPE_SIZE_UNIT (TREE_TYPE (exp)))));
|
||||
|
||||
offset = size_binop (PLUS_EXPR, offset,
|
||||
size_binop (FLOOR_DIV_EXPR, index,
|
||||
size_int (BITS_PER_UNIT)));
|
||||
if (contains_placeholder_p (xindex))
|
||||
xindex = build (WITH_RECORD_EXPR, sizetype, xindex, exp);
|
||||
|
||||
offset = size_binop (PLUS_EXPR, offset, xindex);
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (exp) != NON_LVALUE_EXPR
|
||||
|
@ -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;
|
||||
}
|
||||
|
21
gcc/tree.c
21
gcc/tree.c
@ -2162,16 +2162,17 @@ size_in_bytes (type)
|
||||
|
||||
if (type == error_mark_node)
|
||||
return integer_zero_node;
|
||||
|
||||
type = TYPE_MAIN_VARIANT (type);
|
||||
if (TYPE_SIZE (type) == 0)
|
||||
t = TYPE_SIZE_UNIT (type);
|
||||
if (t == 0)
|
||||
{
|
||||
incomplete_type_error (NULL_TREE, type);
|
||||
return integer_zero_node;
|
||||
}
|
||||
t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
|
||||
size_int (BITS_PER_UNIT));
|
||||
if (TREE_CODE (t) == INTEGER_CST)
|
||||
force_fit_type (t, 0);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
@ -2188,16 +2189,10 @@ int_size_in_bytes (type)
|
||||
return 0;
|
||||
|
||||
type = TYPE_MAIN_VARIANT (type);
|
||||
if (TYPE_SIZE (type) == 0
|
||||
|| TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
|
||||
return -1;
|
||||
|
||||
if (TREE_INT_CST_HIGH (TYPE_SIZE (type)) == 0)
|
||||
return ((TREE_INT_CST_LOW (TYPE_SIZE (type)) + BITS_PER_UNIT - 1)
|
||||
/ BITS_PER_UNIT);
|
||||
|
||||
t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), size_int (BITS_PER_UNIT));
|
||||
if (TREE_CODE (t) != INTEGER_CST || TREE_INT_CST_HIGH (t) != 0)
|
||||
t = TYPE_SIZE_UNIT (type);
|
||||
if (t == 0
|
||||
|| TREE_CODE (t) != INTEGER_CST
|
||||
|| TREE_INT_CST_HIGH (t) != 0)
|
||||
return -1;
|
||||
|
||||
return TREE_INT_CST_LOW (t);
|
||||
|
@ -714,6 +714,7 @@ struct tree_block
|
||||
|
||||
#define TYPE_UID(NODE) ((NODE)->type.uid)
|
||||
#define TYPE_SIZE(NODE) ((NODE)->type.size)
|
||||
#define TYPE_SIZE_UNIT(NODE) ((NODE)->type.size_unit)
|
||||
#define TYPE_MODE(NODE) ((NODE)->type.mode)
|
||||
#define TYPE_VALUES(NODE) ((NODE)->type.values)
|
||||
#define TYPE_DOMAIN(NODE) ((NODE)->type.values)
|
||||
@ -795,6 +796,7 @@ struct tree_type
|
||||
char common[sizeof (struct tree_common)];
|
||||
union tree_node *values;
|
||||
union tree_node *size;
|
||||
union tree_node *size_unit;
|
||||
union tree_node *attributes;
|
||||
unsigned uid;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user