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
This commit is contained in:
parent
b3ec52d088
commit
4d948885d0
23 changed files with 235 additions and 183 deletions
|
@ -1,3 +1,49 @@
|
|||
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.
|
||||
|
||||
2010-09-03 Mingjie Xing <mingjie.xing@gmail.com>
|
||||
|
||||
* config/mips/mips.h (SHIFT_COUNT_TRUNCATED): Change the definition.
|
||||
|
|
|
@ -301,14 +301,14 @@ ao_ref_from_mem (ao_ref *ref, const_rtx mem)
|
|||
ref->base = build_simple_mem_ref (*(tree *)namep);
|
||||
}
|
||||
else if (TREE_CODE (base) == TARGET_MEM_REF
|
||||
&& TMR_SYMBOL (base)
|
||||
&& TREE_CODE (TREE_OPERAND (TMR_SYMBOL (base), 0)) == VAR_DECL
|
||||
&& ! TREE_STATIC (TREE_OPERAND (TMR_SYMBOL (base), 0))
|
||||
&& TREE_CODE (TMR_BASE (base)) == ADDR_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (TMR_BASE (base), 0)) == VAR_DECL
|
||||
&& ! TREE_STATIC (TREE_OPERAND (TMR_BASE (base), 0))
|
||||
&& cfun->gimple_df->decls_to_pointers != NULL)
|
||||
{
|
||||
void *namep;
|
||||
namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers,
|
||||
TREE_OPERAND (TMR_SYMBOL (base), 0));
|
||||
TREE_OPERAND (TMR_BASE (base), 0));
|
||||
if (namep)
|
||||
ref->base = build_simple_mem_ref (*(tree *)namep);
|
||||
}
|
||||
|
|
|
@ -331,9 +331,7 @@ get_object_alignment (tree exp, unsigned int max_align)
|
|||
max_align));
|
||||
bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
|
||||
}
|
||||
else if (TREE_CODE (exp) == TARGET_MEM_REF
|
||||
&& TMR_BASE (exp)
|
||||
&& POINTER_TYPE_P (TREE_TYPE (TMR_BASE (exp))))
|
||||
else if (TREE_CODE (exp) == TARGET_MEM_REF)
|
||||
{
|
||||
struct ptr_info_def *pi;
|
||||
tree addr = TMR_BASE (exp);
|
||||
|
@ -365,22 +363,7 @@ get_object_alignment (tree exp, unsigned int max_align)
|
|||
}
|
||||
else if (TMR_INDEX (exp))
|
||||
align = BITS_PER_UNIT;
|
||||
}
|
||||
else if (TREE_CODE (exp) == TARGET_MEM_REF
|
||||
&& TMR_SYMBOL (exp))
|
||||
{
|
||||
align = get_object_alignment (TREE_OPERAND (TMR_SYMBOL (exp), 0),
|
||||
max_align);
|
||||
if (TMR_OFFSET (exp))
|
||||
bitpos += TREE_INT_CST_LOW (TMR_OFFSET (exp)) * BITS_PER_UNIT;
|
||||
if (TMR_INDEX (exp) && TMR_STEP (exp))
|
||||
{
|
||||
unsigned HOST_WIDE_INT step = TREE_INT_CST_LOW (TMR_STEP (exp));
|
||||
align = MIN (align, (step & -step) * BITS_PER_UNIT);
|
||||
}
|
||||
else if (TMR_INDEX (exp))
|
||||
align = BITS_PER_UNIT;
|
||||
if (TMR_BASE (exp))
|
||||
if (TMR_INDEX2 (exp))
|
||||
align = BITS_PER_UNIT;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -2468,8 +2468,8 @@ expand_debug_expr (tree exp)
|
|||
return op0;
|
||||
|
||||
case TARGET_MEM_REF:
|
||||
if (TMR_SYMBOL (exp)
|
||||
&& !DECL_RTL_SET_P (TREE_OPERAND (TMR_SYMBOL (exp), 0)))
|
||||
if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR
|
||||
&& !DECL_RTL_SET_P (TREE_OPERAND (TMR_BASE (exp), 0)))
|
||||
return NULL;
|
||||
|
||||
op0 = expand_debug_expr
|
||||
|
|
|
@ -528,6 +528,18 @@ maybe_fold_reference (tree expr, bool is_lhs)
|
|||
return expr;
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (*t) == TARGET_MEM_REF)
|
||||
{
|
||||
tree tem = maybe_fold_tmr (*t);
|
||||
if (tem)
|
||||
{
|
||||
*t = tem;
|
||||
tem = maybe_fold_reference (expr, is_lhs);
|
||||
if (tem)
|
||||
return tem;
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
else if (!is_lhs
|
||||
&& DECL_P (*t))
|
||||
{
|
||||
|
@ -602,9 +614,6 @@ fold_gimple_assign (gimple_stmt_iterator *si)
|
|||
COND_EXPR_THEN (rhs), COND_EXPR_ELSE (rhs));
|
||||
}
|
||||
|
||||
else if (TREE_CODE (rhs) == TARGET_MEM_REF)
|
||||
return maybe_fold_tmr (rhs);
|
||||
|
||||
else if (REFERENCE_CLASS_P (rhs))
|
||||
return maybe_fold_reference (rhs, false);
|
||||
|
||||
|
|
11
gcc/gimple.c
11
gcc/gimple.c
|
@ -3004,18 +3004,17 @@ get_base_address (tree t)
|
|||
while (handled_component_p (t))
|
||||
t = TREE_OPERAND (t, 0);
|
||||
|
||||
if (TREE_CODE (t) == MEM_REF
|
||||
if ((TREE_CODE (t) == MEM_REF
|
||||
|| TREE_CODE (t) == TARGET_MEM_REF)
|
||||
&& TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
|
||||
t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
|
||||
else if (TREE_CODE (t) == TARGET_MEM_REF
|
||||
&& TMR_SYMBOL (t))
|
||||
t = TREE_OPERAND (TMR_SYMBOL (t), 0);
|
||||
|
||||
if (SSA_VAR_P (t)
|
||||
|| TREE_CODE (t) == STRING_CST
|
||||
|| TREE_CODE (t) == CONSTRUCTOR
|
||||
|| INDIRECT_REF_P (t)
|
||||
|| TREE_CODE (t) == MEM_REF)
|
||||
|| TREE_CODE (t) == MEM_REF
|
||||
|| TREE_CODE (t) == TARGET_MEM_REF)
|
||||
return t;
|
||||
else
|
||||
return NULL_TREE;
|
||||
|
@ -4725,7 +4724,6 @@ walk_stmt_load_store_addr_ops (gimple stmt, void *data,
|
|||
if (TREE_CODE (rhs) == ADDR_EXPR)
|
||||
ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), data);
|
||||
else if (TREE_CODE (rhs) == TARGET_MEM_REF
|
||||
&& TMR_BASE (rhs) != NULL_TREE
|
||||
&& TREE_CODE (TMR_BASE (rhs)) == ADDR_EXPR)
|
||||
ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (rhs), 0), data);
|
||||
else if (TREE_CODE (rhs) == OBJ_TYPE_REF
|
||||
|
@ -4734,7 +4732,6 @@ walk_stmt_load_store_addr_ops (gimple stmt, void *data,
|
|||
0), data);
|
||||
lhs = gimple_assign_lhs (stmt);
|
||||
if (TREE_CODE (lhs) == TARGET_MEM_REF
|
||||
&& TMR_BASE (lhs) != NULL_TREE
|
||||
&& TREE_CODE (TMR_BASE (lhs)) == ADDR_EXPR)
|
||||
ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (lhs), 0), data);
|
||||
}
|
||||
|
|
|
@ -6977,20 +6977,15 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
|
|||
{
|
||||
enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
|
||||
|
||||
if (TMR_SYMBOL (*expr_p))
|
||||
/* We can't gimplify the symbol part. Assert it is
|
||||
already gimple instead.
|
||||
??? This isn't exactly the same as ADDR_EXPR
|
||||
plus is_gimple_mem_ref_addr (), see fixed_address_object_p. */
|
||||
gcc_assert (TREE_CODE (TMR_SYMBOL (*expr_p)) == ADDR_EXPR
|
||||
&& (TREE_CODE (TREE_OPERAND (TMR_SYMBOL (*expr_p), 0))
|
||||
== VAR_DECL));
|
||||
if (TMR_BASE (*expr_p))
|
||||
r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
|
||||
post_p, is_gimple_val, fb_either);
|
||||
post_p, is_gimple_mem_ref_addr, fb_either);
|
||||
if (TMR_INDEX (*expr_p))
|
||||
r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
|
||||
post_p, is_gimple_val, fb_rvalue);
|
||||
if (TMR_INDEX2 (*expr_p))
|
||||
r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
|
||||
post_p, is_gimple_val, fb_rvalue);
|
||||
/* TMR_STEP and TMR_OFFSET are always integer constants. */
|
||||
ret = MIN (r0, r1);
|
||||
}
|
||||
|
|
|
@ -2990,11 +2990,10 @@ verify_types_in_gimple_reference (tree expr, bool require_lvalue)
|
|||
}
|
||||
else if (TREE_CODE (expr) == TARGET_MEM_REF)
|
||||
{
|
||||
if (TMR_SYMBOL (expr)
|
||||
&& TMR_BASE (expr)
|
||||
&& !useless_type_conversion_p (sizetype, TREE_TYPE (TMR_BASE (expr))))
|
||||
if (!TMR_BASE (expr)
|
||||
|| !is_gimple_mem_ref_addr (TMR_BASE (expr)))
|
||||
{
|
||||
error ("Non-sizetype base in TARGET_MEM_REF with symbol");
|
||||
error ("Invalid address operand in in TARGET_MEM_REF.");
|
||||
return true;
|
||||
}
|
||||
if (!TMR_OFFSET (expr)
|
||||
|
|
|
@ -880,19 +880,19 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
|||
|
||||
case TARGET_MEM_REF:
|
||||
/* Hand back the decl for MEM[&decl, off]. */
|
||||
if (TMR_SYMBOL (exp))
|
||||
if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR)
|
||||
{
|
||||
/* Via the variable index or base we can reach the
|
||||
/* Via the variable index or index2 we can reach the
|
||||
whole object. */
|
||||
if (TMR_INDEX (exp) || TMR_BASE (exp))
|
||||
if (TMR_INDEX (exp) || TMR_INDEX2 (exp))
|
||||
{
|
||||
exp = TREE_OPERAND (TMR_SYMBOL (exp), 0);
|
||||
exp = TREE_OPERAND (TMR_BASE (exp), 0);
|
||||
bit_offset = 0;
|
||||
maxsize = -1;
|
||||
goto done;
|
||||
}
|
||||
if (integer_zerop (TMR_OFFSET (exp)))
|
||||
exp = TREE_OPERAND (TMR_SYMBOL (exp), 0);
|
||||
exp = TREE_OPERAND (TMR_BASE (exp), 0);
|
||||
else
|
||||
{
|
||||
double_int off = mem_ref_offset (exp);
|
||||
|
@ -904,7 +904,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
|||
if (double_int_fits_in_shwi_p (off))
|
||||
{
|
||||
bit_offset = double_int_to_shwi (off);
|
||||
exp = TREE_OPERAND (TMR_SYMBOL (exp), 0);
|
||||
exp = TREE_OPERAND (TMR_BASE (exp), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1044,9 +1044,9 @@ get_addr_base_and_unit_offset (tree exp, HOST_WIDE_INT *poffset)
|
|||
|
||||
case TARGET_MEM_REF:
|
||||
/* Hand back the decl for MEM[&decl, off]. */
|
||||
if (TMR_SYMBOL (exp))
|
||||
if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR)
|
||||
{
|
||||
if (TMR_INDEX (exp) || TMR_BASE (exp))
|
||||
if (TMR_INDEX (exp) || TMR_INDEX2 (exp))
|
||||
return NULL_TREE;
|
||||
if (!integer_zerop (TMR_OFFSET (exp)))
|
||||
{
|
||||
|
@ -1054,7 +1054,7 @@ get_addr_base_and_unit_offset (tree exp, HOST_WIDE_INT *poffset)
|
|||
gcc_assert (off.high == -1 || off.high == 0);
|
||||
byte_offset += double_int_to_shwi (off);
|
||||
}
|
||||
exp = TREE_OPERAND (TMR_SYMBOL (exp), 0);
|
||||
exp = TREE_OPERAND (TMR_BASE (exp), 0);
|
||||
}
|
||||
goto done;
|
||||
|
||||
|
|
|
@ -2404,8 +2404,8 @@ tree_could_trap_p (tree expr)
|
|||
switch (code)
|
||||
{
|
||||
case TARGET_MEM_REF:
|
||||
if (TMR_SYMBOL (expr)
|
||||
&& !TMR_INDEX (expr) && !TMR_BASE (expr))
|
||||
if (TREE_CODE (TMR_BASE (expr)) == ADDR_EXPR
|
||||
&& !TMR_INDEX (expr) && !TMR_INDEX2 (expr))
|
||||
return false;
|
||||
return !TREE_THIS_NOTRAP (expr);
|
||||
|
||||
|
|
|
@ -852,16 +852,22 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
|
|||
|
||||
pp_string (buffer, "MEM[");
|
||||
|
||||
tmp = TMR_SYMBOL (node);
|
||||
if (tmp)
|
||||
if (TREE_CODE (TMR_BASE (node)) == ADDR_EXPR)
|
||||
{
|
||||
pp_string (buffer, sep);
|
||||
sep = ", ";
|
||||
pp_string (buffer, "symbol: ");
|
||||
dump_generic_node (buffer, TREE_OPERAND (tmp, 0),
|
||||
dump_generic_node (buffer, TREE_OPERAND (TMR_BASE (node), 0),
|
||||
spc, flags, false);
|
||||
}
|
||||
tmp = TMR_BASE (node);
|
||||
else
|
||||
{
|
||||
pp_string (buffer, sep);
|
||||
sep = ", ";
|
||||
pp_string (buffer, "base: ");
|
||||
dump_generic_node (buffer, TMR_BASE (node), spc, flags, false);
|
||||
}
|
||||
tmp = TMR_INDEX2 (node);
|
||||
if (tmp)
|
||||
{
|
||||
pp_string (buffer, sep);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -670,21 +670,7 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
|
|||
tree ptrtype1;
|
||||
HOST_WIDE_INT offset1p = offset1, offset2p = offset2;
|
||||
|
||||
if (TREE_CODE (base1) == TARGET_MEM_REF)
|
||||
{
|
||||
if (TMR_SYMBOL (base1))
|
||||
ptr1 = TMR_SYMBOL (base1);
|
||||
else if (TMR_BASE (base1))
|
||||
{
|
||||
if (!POINTER_TYPE_P (TREE_TYPE (TMR_BASE (base1))))
|
||||
return true;
|
||||
ptr1 = TMR_BASE (base1);
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
ptr1 = TREE_OPERAND (base1, 0);
|
||||
ptr1 = TREE_OPERAND (base1, 0);
|
||||
|
||||
/* The offset embedded in MEM_REFs can be negative. Bias them
|
||||
so that the resulting offset adjustment is positive. */
|
||||
|
@ -812,37 +798,8 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
|
|||
tree ptr2;
|
||||
tree ptrtype1, ptrtype2;
|
||||
|
||||
if (TREE_CODE (base1) == TARGET_MEM_REF)
|
||||
{
|
||||
if (TMR_SYMBOL (base1))
|
||||
ptr1 = TMR_SYMBOL (base1);
|
||||
else if (TMR_BASE (base1))
|
||||
{
|
||||
if (!POINTER_TYPE_P (TREE_TYPE (TMR_BASE (base1))))
|
||||
return true;
|
||||
ptr1 = TMR_BASE (base1);
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
ptr1 = TREE_OPERAND (base1, 0);
|
||||
|
||||
if (TREE_CODE (base2) == TARGET_MEM_REF)
|
||||
{
|
||||
if (TMR_SYMBOL (base2))
|
||||
ptr2 = TMR_SYMBOL (base2);
|
||||
else if (TMR_BASE (base2))
|
||||
{
|
||||
if (!POINTER_TYPE_P (TREE_TYPE (TMR_BASE (base2))))
|
||||
return true;
|
||||
ptr2 = TMR_BASE (base2);
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
ptr2 = TREE_OPERAND (base2, 0);
|
||||
ptr1 = TREE_OPERAND (base1, 0);
|
||||
ptr2 = TREE_OPERAND (base2, 0);
|
||||
|
||||
/* If both bases are based on pointers they cannot alias if they may not
|
||||
point to the same memory object or if they point to the same object
|
||||
|
|
|
@ -362,13 +362,13 @@ mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data)
|
|||
&& (b = TREE_BLOCK (t)) != NULL)
|
||||
TREE_USED (b) = true;
|
||||
|
||||
/* Ignore TREE_ORIGINAL for TARGET_MEM_REFS, as well as other
|
||||
fields that do not contain vars. */
|
||||
/* Ignore TMR_OFFSET and TMR_STEP for TARGET_MEM_REFS, as those
|
||||
fields do not contain vars. */
|
||||
if (TREE_CODE (t) == TARGET_MEM_REF)
|
||||
{
|
||||
mark_all_vars_used (&TMR_SYMBOL (t), data);
|
||||
mark_all_vars_used (&TMR_BASE (t), data);
|
||||
mark_all_vars_used (&TMR_INDEX (t), data);
|
||||
mark_all_vars_used (&TMR_INDEX2 (t), data);
|
||||
*walk_subtrees = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -324,6 +324,10 @@ for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
|
|||
&& !cbck (*addr_p, idx, data))
|
||||
return false;
|
||||
idx = &TMR_INDEX (*addr_p);
|
||||
if (*idx
|
||||
&& !cbck (*addr_p, idx, data))
|
||||
return false;
|
||||
idx = &TMR_INDEX2 (*addr_p);
|
||||
if (*idx
|
||||
&& !cbck (*addr_p, idx, data))
|
||||
return false;
|
||||
|
|
|
@ -1722,6 +1722,16 @@ find_interesting_uses_address (struct ivopts_data *data, gimple stmt, tree *op_p
|
|||
TMR_BASE (base) = civ->base;
|
||||
step = civ->step;
|
||||
}
|
||||
if (TMR_INDEX2 (base)
|
||||
&& TREE_CODE (TMR_INDEX2 (base)) == SSA_NAME)
|
||||
{
|
||||
civ = get_iv (data, TMR_INDEX2 (base));
|
||||
if (!civ)
|
||||
goto fail;
|
||||
|
||||
TMR_INDEX2 (base) = civ->base;
|
||||
step = civ->step;
|
||||
}
|
||||
if (TMR_INDEX (base)
|
||||
&& TREE_CODE (TMR_INDEX (base)) == SSA_NAME)
|
||||
{
|
||||
|
@ -1778,9 +1788,14 @@ find_interesting_uses_address (struct ivopts_data *data, gimple stmt, tree *op_p
|
|||
ref = &TREE_OPERAND (*ref, 0);
|
||||
if (TREE_CODE (*ref) == MEM_REF)
|
||||
{
|
||||
tree tem = fold_binary (MEM_REF, TREE_TYPE (*ref),
|
||||
TREE_OPERAND (*ref, 0),
|
||||
TREE_OPERAND (*ref, 1));
|
||||
tree tem = TREE_OPERAND (*ref, 0);
|
||||
STRIP_NOPS (tem);
|
||||
if (tem != TREE_OPERAND (*ref, 0))
|
||||
tem = fold_build2 (MEM_REF, TREE_TYPE (*ref),
|
||||
tem, TREE_OPERAND (*ref, 1));
|
||||
else
|
||||
tem = fold_binary (MEM_REF, TREE_TYPE (*ref),
|
||||
tem, TREE_OPERAND (*ref, 1));
|
||||
if (tem)
|
||||
*ref = tem;
|
||||
}
|
||||
|
|
|
@ -754,9 +754,7 @@ get_tmr_operands (gimple stmt, tree expr, int flags)
|
|||
/* First record the real operands. */
|
||||
get_expr_operands (stmt, &TMR_BASE (expr), opf_use | (flags & opf_no_vops));
|
||||
get_expr_operands (stmt, &TMR_INDEX (expr), opf_use | (flags & opf_no_vops));
|
||||
|
||||
if (TMR_SYMBOL (expr))
|
||||
mark_address_taken (TREE_OPERAND (TMR_SYMBOL (expr), 0));
|
||||
get_expr_operands (stmt, &TMR_INDEX2 (expr), opf_use | (flags & opf_no_vops));
|
||||
|
||||
add_virtual_operand (stmt, flags);
|
||||
}
|
||||
|
|
|
@ -2772,8 +2772,10 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
|
|||
break;
|
||||
case TARGET_MEM_REF:
|
||||
{
|
||||
pre_expr op0expr;
|
||||
tree genop0 = NULL_TREE;
|
||||
pre_expr op0expr, op1expr;
|
||||
tree genop0 = NULL_TREE, genop1 = NULL_TREE;
|
||||
vn_reference_op_t nextop = VEC_index (vn_reference_op_s, ref->operands,
|
||||
++*operand);
|
||||
tree baseop = create_component_ref_by_pieces_1 (block, ref, operand,
|
||||
stmts, domstmt);
|
||||
if (!baseop)
|
||||
|
@ -2786,14 +2788,16 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
|
|||
if (!genop0)
|
||||
return NULL_TREE;
|
||||
}
|
||||
if (DECL_P (baseop))
|
||||
return build5 (TARGET_MEM_REF, currop->type,
|
||||
baseop, NULL_TREE,
|
||||
genop0, currop->op1, currop->op2);
|
||||
else
|
||||
return build5 (TARGET_MEM_REF, currop->type,
|
||||
NULL_TREE, baseop,
|
||||
genop0, currop->op1, currop->op2);
|
||||
if (nextop->op0)
|
||||
{
|
||||
op1expr = get_or_alloc_expr_for (nextop->op0);
|
||||
genop1 = find_or_generate_expression (block, op1expr,
|
||||
stmts, domstmt);
|
||||
if (!genop1)
|
||||
return NULL_TREE;
|
||||
}
|
||||
return build5 (TARGET_MEM_REF, currop->type,
|
||||
baseop, currop->op2, genop0, currop->op1, genop1);
|
||||
}
|
||||
break;
|
||||
case ADDR_EXPR:
|
||||
|
|
|
@ -575,11 +575,6 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
|
|||
if (TREE_CODE (ref) == TARGET_MEM_REF)
|
||||
{
|
||||
vn_reference_op_s temp;
|
||||
tree base;
|
||||
|
||||
base = TMR_SYMBOL (ref) ? TMR_SYMBOL (ref) : TMR_BASE (ref);
|
||||
if (!base)
|
||||
base = null_pointer_node;
|
||||
|
||||
memset (&temp, 0, sizeof (temp));
|
||||
/* We do not care for spurious type qualifications. */
|
||||
|
@ -593,8 +588,15 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
|
|||
|
||||
memset (&temp, 0, sizeof (temp));
|
||||
temp.type = NULL_TREE;
|
||||
temp.opcode = TREE_CODE (base);
|
||||
temp.op0 = base;
|
||||
temp.opcode = ERROR_MARK;
|
||||
temp.op0 = TMR_INDEX2 (ref);
|
||||
temp.off = -1;
|
||||
VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
|
||||
|
||||
memset (&temp, 0, sizeof (temp));
|
||||
temp.type = NULL_TREE;
|
||||
temp.opcode = TREE_CODE (TMR_BASE (ref));
|
||||
temp.op0 = TMR_BASE (ref);
|
||||
temp.off = -1;
|
||||
VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
|
||||
return;
|
||||
|
|
|
@ -191,7 +191,8 @@ is_hidden_global_store (gimple stmt)
|
|||
|
||||
}
|
||||
else if (INDIRECT_REF_P (lhs)
|
||||
|| TREE_CODE (lhs) == MEM_REF)
|
||||
|| TREE_CODE (lhs) == MEM_REF
|
||||
|| TREE_CODE (lhs) == TARGET_MEM_REF)
|
||||
return ptr_deref_may_alias_global_p (TREE_OPERAND (lhs, 0));
|
||||
else if (CONSTANT_CLASS_P (lhs))
|
||||
return true;
|
||||
|
|
|
@ -3910,7 +3910,7 @@ build_simple_mem_ref_loc (location_t loc, tree ptr)
|
|||
double_int
|
||||
mem_ref_offset (const_tree t)
|
||||
{
|
||||
tree toff = TREE_CODE (t) == MEM_REF ? TREE_OPERAND (t, 1) : TMR_OFFSET (t);
|
||||
tree toff = TREE_OPERAND (t, 1);
|
||||
return double_int_sext (tree_to_double_int (toff),
|
||||
TYPE_PRECISION (TREE_TYPE (toff)));
|
||||
}
|
||||
|
|
16
gcc/tree.def
16
gcc/tree.def
|
@ -952,14 +952,16 @@ DEFTREECODE (WITH_SIZE_EXPR, "with_size_expr", tcc_expression, 2)
|
|||
generated by the builtin targetm.vectorize.mask_for_load_builtin_decl. */
|
||||
DEFTREECODE (REALIGN_LOAD_EXPR, "realign_load", tcc_expression, 3)
|
||||
|
||||
/* Low-level memory addressing. Operands are SYMBOL (address of static or
|
||||
global variable), BASE (register), INDEX (register), STEP (integer constant),
|
||||
OFFSET (integer constant). Corresponding address is
|
||||
SYMBOL + BASE + STEP * INDEX + OFFSET. Only variations and values valid on
|
||||
the target are allowed.
|
||||
/* Low-level memory addressing. Operands are BASE (address of static or
|
||||
global variable or register), OFFSET (integer constant),
|
||||
INDEX (register), STEP (integer constant), INDEX2 (register),
|
||||
The corresponding address is BASE + STEP * INDEX + INDEX2 + OFFSET.
|
||||
Only variations and values valid on the target are allowed.
|
||||
|
||||
The type of STEP and INDEX is sizetype. The type of BASE is
|
||||
sizetype or a pointer type (if SYMBOL is NULL).
|
||||
The type of STEP, INDEX and INDEX2 is sizetype.
|
||||
|
||||
The type of BASE is a pointer type. If BASE is not an address of
|
||||
a static or global variable INDEX2 will be NULL.
|
||||
|
||||
The type of OFFSET is a pointer type and determines TBAA the same as
|
||||
the constant offset operand in MEM_REF. */
|
||||
|
|
|
@ -1632,12 +1632,13 @@ extern void protected_set_expr_location (tree, location_t);
|
|||
#define CASE_HIGH(NODE) TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 1)
|
||||
#define CASE_LABEL(NODE) TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 2)
|
||||
|
||||
/* The operands of a TARGET_MEM_REF. */
|
||||
#define TMR_SYMBOL(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 0))
|
||||
#define TMR_BASE(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 1))
|
||||
/* The operands of a TARGET_MEM_REF. Operands 0 and 1 have to match
|
||||
corresponding MEM_REF operands. */
|
||||
#define TMR_BASE(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 0))
|
||||
#define TMR_OFFSET(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 1))
|
||||
#define TMR_INDEX(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 2))
|
||||
#define TMR_STEP(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 3))
|
||||
#define TMR_OFFSET(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 4))
|
||||
#define TMR_INDEX2(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 4))
|
||||
|
||||
/* The operands of a BIND_EXPR. */
|
||||
#define BIND_EXPR_VARS(NODE) (TREE_OPERAND (BIND_EXPR_CHECK (NODE), 0))
|
||||
|
|
Loading…
Add table
Reference in a new issue