aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-address.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-09-03 09:50:17 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-09-03 09:50:17 +0000
commit4d948885d0d10918e53b9d91fde81c4f47d837a8 (patch)
tree906679b413fe977c9a6b6281ce7ba070a3cf8a52 /gcc/tree-ssa-address.c
parentb3ec52d088106728c7c8acda2e736e09b6e70b4f (diff)
downloadgcc-4d948885d0d10918e53b9d91fde81c4f47d837a8.zip
gcc-4d948885d0d10918e53b9d91fde81c4f47d837a8.tar.gz
gcc-4d948885d0d10918e53b9d91fde81c4f47d837a8.tar.bz2
tree.def (TARGET_MEM_REF): Merge TMR_SYMBOL and TMR_BASE.
2010-09-03 Richard Guenther <rguenther@suse.de> * tree.def (TARGET_MEM_REF): Merge TMR_SYMBOL and TMR_BASE. Move TMR_OFFSET to second operand. Add TMR_INDEX2. * tree.h (TMR_SYMBOL): Remove. (TMR_BASE, TMR_OFFSET): Adjust. (TMR_INDEX2): New. * alias.c (ao_ref_from_mem): Use TMR_BASE. * builtins.c (get_object_alignment): Merge TMR_BASE and TMR_SYMBOL handling. * cfgexpand.c (expand_debug_expr): Use TMR_BASE. * gimple.c (get_base_address): Merge MEM_REF and TARGET_MEM_REF handling. Also allow TARGET_MEM_REF as base address. (walk_stmt_load_store_addr_ops): TMR_BASE is always non-NULL. * gimplify.c (gimplify_expr): Gimplify TMR_BASE like MEM_REF base. Gimplify TMR_INDEX2. * tree-cfg.c (verify_types_in_gimple_reference): Adjust. * tree-dfa.c (get_ref_base_and_extent): Likewise. (get_addr_base_and_unit_offset): Likewise. * tree-eh.c (tree_could_trap_p): Likewise. * tree-pretty-print.c (dump_generic_node): Likewise. * tree-ssa-address.c (tree_mem_ref_addr): Simplify. Handle TMR_INDEX2. (create_mem_ref_raw): Merge symbol and base. Move 2ndary base to index2. (get_address_description): Reconstruct addres description from merged TMR_BASE and TMR_INDEX2. (maybe_fold_tmr): Fold propagated addresses. * tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Merge MEM_REF and TARGET_MEM_REF paths. (indirect_refs_may_alias_p): Likewise. * tree-ssa-live.c (mark_all_vars_used_1): Handle TMR_INDEX2 instead of TMR_SYMBOL. * tree-ssa-operands.c (get_tmr_operands): Simplify. * tree-ssa-pre.c (create_component_ref_by_pieces_1): Adjust according to changes ... * tree-ssa-sccvn.c (copy_reference_ops_from_ref): ... here. Split TARGET_MEM_REF into two fields plus the base. * tree.c (mem_ref_offset): Simplify. * tree-ssa-loop-im.c (for_each_index): Handle TMR_INDEX2. * tree-ssa-loop-ivopts.c (find_interesting_uses_address): Likewise. Strip NOPs when folding MEM_REF addresses. * tree-ssa-sink.c (is_hidden_global_store): Handle TARGET_MEM_REF. * gimple-fold.c (maybe_fold_reference): Fold TARGET_MEM_REF here ... (fold_gimple_assign): ... not here. From-SVN: r163802
Diffstat (limited to 'gcc/tree-ssa-address.c')
-rw-r--r--gcc/tree-ssa-address.c103
1 files changed, 68 insertions, 35 deletions
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
index d642425..99b87bb 100644
--- a/gcc/tree-ssa-address.c
+++ b/gcc/tree-ssa-address.c
@@ -268,17 +268,9 @@ tree_mem_ref_addr (tree type, tree mem_ref)
tree addr;
tree act_elem;
tree step = TMR_STEP (mem_ref), offset = TMR_OFFSET (mem_ref);
- tree sym = TMR_SYMBOL (mem_ref), base = TMR_BASE (mem_ref);
tree addr_base = NULL_TREE, addr_off = NULL_TREE;
- if (sym)
- addr_base = fold_convert (type, sym);
- else if (base)
- {
- gcc_assert (POINTER_TYPE_P (TREE_TYPE (base)));
- addr_base = fold_convert (type, base);
- base = NULL_TREE;
- }
+ addr_base = fold_convert (type, TMR_BASE (mem_ref));
act_elem = TMR_INDEX (mem_ref);
if (act_elem)
@@ -288,7 +280,7 @@ tree_mem_ref_addr (tree type, tree mem_ref)
addr_off = act_elem;
}
- act_elem = base;
+ act_elem = TMR_INDEX2 (mem_ref);
if (act_elem)
{
if (addr_off)
@@ -307,16 +299,9 @@ tree_mem_ref_addr (tree type, tree mem_ref)
}
if (addr_off)
- {
- if (addr_base)
- addr = fold_build2 (POINTER_PLUS_EXPR, type, addr_base, addr_off);
- else
- addr = fold_convert (type, addr_off);
- }
- else if (addr_base)
- addr = addr_base;
+ addr = fold_build2 (POINTER_PLUS_EXPR, type, addr_base, addr_off);
else
- addr = build_int_cst (type, 0);
+ addr = addr_base;
return addr;
}
@@ -344,6 +329,8 @@ valid_mem_ref_p (enum machine_mode mode, addr_space_t as,
static tree
create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr)
{
+ tree base, index2;
+
if (!valid_mem_ref_p (TYPE_MODE (type), TYPE_ADDR_SPACE (type), addr))
return NULL_TREE;
@@ -355,23 +342,31 @@ create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr)
else
addr->offset = build_int_cst (alias_ptr_type, 0);
- /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF. */
- if (alias_ptr_type
- && (!addr->index || integer_zerop (addr->index))
- && (!addr->base || POINTER_TYPE_P (TREE_TYPE (addr->base))))
+ if (addr->symbol)
{
- tree base;
- gcc_assert (!addr->symbol ^ !addr->base);
- if (addr->symbol)
- base = addr->symbol;
- else
- base = addr->base;
- return fold_build2 (MEM_REF, type, base, addr->offset);
+ base = addr->symbol;
+ index2 = addr->base;
+ }
+ else if (addr->base
+ && POINTER_TYPE_P (TREE_TYPE (addr->base)))
+ {
+ base = addr->base;
+ index2 = NULL_TREE;
}
+ else
+ {
+ base = build_int_cst (ptr_type_node, 0);
+ index2 = addr->base;
+ }
+
+ /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF. */
+ if (alias_ptr_type
+ && (!index2 || integer_zerop (index2))
+ && (!addr->index || integer_zerop (addr->index)))
+ return fold_build2 (MEM_REF, type, base, addr->offset);
return build5 (TARGET_MEM_REF, type,
- addr->symbol, addr->base, addr->index,
- addr->step, addr->offset);
+ base, addr->offset, addr->index, addr->step, index2);
}
/* Returns true if OBJ is an object whose address is a link time constant. */
@@ -808,8 +803,22 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
void
get_address_description (tree op, struct mem_address *addr)
{
- addr->symbol = TMR_SYMBOL (op);
- addr->base = TMR_BASE (op);
+ if (TREE_CODE (TMR_BASE (op)) == ADDR_EXPR)
+ {
+ addr->symbol = TMR_BASE (op);
+ addr->base = TMR_INDEX2 (op);
+ }
+ else
+ {
+ addr->symbol = NULL_TREE;
+ if (TMR_INDEX2 (op))
+ {
+ gcc_assert (integer_zerop (TMR_BASE (op)));
+ addr->base = TMR_INDEX2 (op);
+ }
+ else
+ addr->base = TMR_BASE (op);
+ }
addr->index = TMR_INDEX (op);
addr->step = TMR_STEP (op);
addr->offset = TMR_OFFSET (op);
@@ -837,7 +846,9 @@ maybe_fold_tmr (tree ref)
get_address_description (ref, &addr);
- if (addr.base && TREE_CODE (addr.base) == INTEGER_CST)
+ if (addr.base
+ && TREE_CODE (addr.base) == INTEGER_CST
+ && !integer_zerop (addr.base))
{
addr.offset = fold_binary_to_constant (PLUS_EXPR,
TREE_TYPE (addr.offset),
@@ -846,6 +857,28 @@ maybe_fold_tmr (tree ref)
changed = true;
}
+ if (addr.symbol
+ && TREE_CODE (TREE_OPERAND (addr.symbol, 0)) == MEM_REF)
+ {
+ addr.offset = fold_binary_to_constant
+ (PLUS_EXPR, TREE_TYPE (addr.offset),
+ addr.offset,
+ TREE_OPERAND (TREE_OPERAND (addr.symbol, 0), 1));
+ addr.symbol = TREE_OPERAND (TREE_OPERAND (addr.symbol, 0), 0);
+ changed = true;
+ }
+ else if (addr.symbol
+ && handled_component_p (TREE_OPERAND (addr.symbol, 0)))
+ {
+ HOST_WIDE_INT offset;
+ addr.symbol = build_fold_addr_expr
+ (get_addr_base_and_unit_offset
+ (TREE_OPERAND (addr.symbol, 0), &offset));
+ addr.offset = int_const_binop (PLUS_EXPR,
+ addr.offset, size_int (offset), 0);
+ changed = true;
+ }
+
if (addr.index && TREE_CODE (addr.index) == INTEGER_CST)
{
off = addr.index;