diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-30 03:52:37 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-30 03:52:37 +0000 |
commit | 1f9b622bb72fbb8256bff4899b2f97cb4c5f5867 (patch) | |
tree | 4b6086cd760db3d4e0eef4da7e0f58d8a24f0d0a /gcc/expr.c | |
parent | 553b7a5dd591a3c394517fb52def0c483b184db8 (diff) | |
download | ppe42-gcc-1f9b622bb72fbb8256bff4899b2f97cb4c5f5867.tar.gz ppe42-gcc-1f9b622bb72fbb8256bff4899b2f97cb4c5f5867.zip |
* expr.c (get_inner_reference): Handle REAL/IMAGPART_EXPR.
(handled_component_p): Likewise.
* alias.c (can_address_p): Reformat and simplify. Handle
REAL/IMAGPART_EXPR. Do not disable addressability based on
alias set zero.
* fold-const.c (build_fold_addr_expr_with_type): Remove duplicate
check for REAL/IMAGPART_EXPR.
* gimplify.c (gimplify_compound_lval): Likewise.
* tree-cfg.c (verify_expr): Likewise.
* tree-gimple.c (is_gimple_addressable, get_base_address): Likewise.
* tree-nested.c (build_addr, convert_nonlocal_reference): Likewise.
(convert_local_reference): Likewise.
* tree-ssa-loop-ivopts.c (prepare_decl_rtl): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@91511 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 134 |
1 files changed, 81 insertions, 53 deletions
diff --git a/gcc/expr.c b/gcc/expr.c index e7ae6b59f77..9ab2c4a0b9f 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5311,65 +5311,90 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, and find the ultimate containing object. */ while (1) { - if (TREE_CODE (exp) == BIT_FIELD_REF) - bit_offset = size_binop (PLUS_EXPR, bit_offset, TREE_OPERAND (exp, 2)); - else if (TREE_CODE (exp) == COMPONENT_REF) + switch (TREE_CODE (exp)) { - tree field = TREE_OPERAND (exp, 1); - tree this_offset = component_ref_field_offset (exp); + case BIT_FIELD_REF: + bit_offset = size_binop (PLUS_EXPR, bit_offset, + TREE_OPERAND (exp, 2)); + break; - /* If this field hasn't been filled in yet, don't go - past it. This should only happen when folding expressions - made during type construction. */ - if (this_offset == 0) - break; + case COMPONENT_REF: + { + tree field = TREE_OPERAND (exp, 1); + tree this_offset = component_ref_field_offset (exp); - offset = size_binop (PLUS_EXPR, offset, this_offset); - bit_offset = size_binop (PLUS_EXPR, bit_offset, - DECL_FIELD_BIT_OFFSET (field)); + /* If this field hasn't been filled in yet, don't go past it. + This should only happen when folding expressions made during + type construction. */ + if (this_offset == 0) + break; - /* ??? Right now we don't do anything with DECL_OFFSET_ALIGN. */ - } + offset = size_binop (PLUS_EXPR, offset, this_offset); + bit_offset = size_binop (PLUS_EXPR, bit_offset, + DECL_FIELD_BIT_OFFSET (field)); - else if (TREE_CODE (exp) == ARRAY_REF - || TREE_CODE (exp) == ARRAY_RANGE_REF) - { - tree index = TREE_OPERAND (exp, 1); - tree low_bound = array_ref_low_bound (exp); - tree unit_size = array_ref_element_size (exp); - - /* We assume all arrays have sizes that are a multiple of a byte. - First subtract the lower bound, if any, in the type of the - index, then convert to sizetype and multiply by the size of the - array element. */ - if (! integer_zerop (low_bound)) - index = fold (build2 (MINUS_EXPR, TREE_TYPE (index), - index, low_bound)); - - offset = size_binop (PLUS_EXPR, offset, - size_binop (MULT_EXPR, - convert (sizetype, index), - unit_size)); - } + /* ??? Right now we don't do anything with DECL_OFFSET_ALIGN. */ + } + break; - /* We can go inside most conversions: all NON_VALUE_EXPRs, all normal - conversions that don't change the mode, and all view conversions - except those that need to "step up" the alignment. */ - else if (TREE_CODE (exp) != NON_LVALUE_EXPR - && ! (TREE_CODE (exp) == VIEW_CONVERT_EXPR - && ! ((TYPE_ALIGN (TREE_TYPE (exp)) - > TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0)))) - && STRICT_ALIGNMENT - && (TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0))) - < BIGGEST_ALIGNMENT) - && (TYPE_ALIGN_OK (TREE_TYPE (exp)) - || TYPE_ALIGN_OK (TREE_TYPE - (TREE_OPERAND (exp, 0)))))) - && ! ((TREE_CODE (exp) == NOP_EXPR - || TREE_CODE (exp) == CONVERT_EXPR) - && (TYPE_MODE (TREE_TYPE (exp)) - == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))) - break; + case ARRAY_REF: + case ARRAY_RANGE_REF: + { + tree index = TREE_OPERAND (exp, 1); + tree low_bound = array_ref_low_bound (exp); + tree unit_size = array_ref_element_size (exp); + + /* We assume all arrays have sizes that are a multiple of a byte. + First subtract the lower bound, if any, in the type of the + index, then convert to sizetype and multiply by the size of + the array element. */ + if (! integer_zerop (low_bound)) + index = fold (build2 (MINUS_EXPR, TREE_TYPE (index), + index, low_bound)); + + offset = size_binop (PLUS_EXPR, offset, + size_binop (MULT_EXPR, + convert (sizetype, index), + unit_size)); + } + break; + + case REALPART_EXPR: + bit_offset = bitsize_zero_node; + break; + + case IMAGPART_EXPR: + bit_offset = build_int_cst (bitsizetype, *pbitsize); + break; + + /* We can go inside most conversions: all NON_VALUE_EXPRs, all normal + conversions that don't change the mode, and all view conversions + except those that need to "step up" the alignment. */ + + case NON_LVALUE_EXPR: + break; + + case NOP_EXPR: + case CONVERT_EXPR: + if (TYPE_MODE (TREE_TYPE (exp)) + != TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))) + goto done; + break; + + case VIEW_CONVERT_EXPR: + if ((TYPE_ALIGN (TREE_TYPE (exp)) + > TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0)))) + && STRICT_ALIGNMENT + && (TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0))) + < BIGGEST_ALIGNMENT) + && (TYPE_ALIGN_OK (TREE_TYPE (exp)) + || TYPE_ALIGN_OK (TREE_TYPE (TREE_OPERAND (exp, 0))))) + goto done; + break; + + default: + goto done; + } /* If any reference in the chain is volatile, the effect is volatile. */ if (TREE_THIS_VOLATILE (exp)) @@ -5377,6 +5402,7 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, exp = TREE_OPERAND (exp, 0); } + done: /* If OFFSET is constant, see if we can return the whole thing as a constant bit position. Otherwise, split it up. */ @@ -5499,6 +5525,8 @@ handled_component_p (tree t) case ARRAY_RANGE_REF: case NON_LVALUE_EXPR: case VIEW_CONVERT_EXPR: + case REALPART_EXPR: + case IMAGPART_EXPR: return 1; /* ??? Sure they are handled, but get_inner_reference may return |