From ead1705900f4e5c6e06407208b928d83b4646320 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 18 May 1998 06:21:14 -0700 Subject: 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 --- gcc/expr.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'gcc/expr.c') diff --git a/gcc/expr.c b/gcc/expr.c index 34f744d..f4e1d21 100644 --- a/gcc/expr.c +++ b/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); - - offset = size_binop (PLUS_EXPR, offset, - size_binop (FLOOR_DIV_EXPR, index, - size_int (BITS_PER_UNIT))); + /* 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))))); + + 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 -- cgit v1.1