tree.c (reference_alias_ptr_type): New function.
2010-07-05 Richard Guenther <rguenther@suse.de> * tree.c (reference_alias_ptr_type): New function. * tree.h (reference_alias_ptr_type): Declare. * tree-ssa-loop-ivopts.c (copy_ref_info): Restructure to allow non-TARGET_MEM_REF new refs. (rewrite_use_address): Pass old alias pointer type to create_mem_ref. * tree-ssa-address.c (create_mem_ref_raw): Get alias pointer type. Build a MEM_REF instead of a TARGET_MEM_REF if possible. (create_mem_ref): Get alias pointer type. Adjust calls to create_mem_ref_raw. (maybe_fold_tmr): Likewise. * tree-flow.h (create_mem_ref): Adjust prototype. From-SVN: r161840
This commit is contained in:
parent
5c144a5fad
commit
a41e5e86c0
|
@ -1,3 +1,18 @@
|
|||
2010-07-05 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* tree.c (reference_alias_ptr_type): New function.
|
||||
* tree.h (reference_alias_ptr_type): Declare.
|
||||
* tree-ssa-loop-ivopts.c (copy_ref_info): Restructure to
|
||||
allow non-TARGET_MEM_REF new refs.
|
||||
(rewrite_use_address): Pass old alias pointer type to
|
||||
create_mem_ref.
|
||||
* tree-ssa-address.c (create_mem_ref_raw): Get alias pointer type.
|
||||
Build a MEM_REF instead of a TARGET_MEM_REF if possible.
|
||||
(create_mem_ref): Get alias pointer type. Adjust calls to
|
||||
create_mem_ref_raw.
|
||||
(maybe_fold_tmr): Likewise.
|
||||
* tree-flow.h (create_mem_ref): Adjust prototype.
|
||||
|
||||
2010-07-05 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/44808
|
||||
|
|
|
@ -833,7 +833,7 @@ struct mem_address
|
|||
};
|
||||
|
||||
struct affine_tree_combination;
|
||||
tree create_mem_ref (gimple_stmt_iterator *, tree,
|
||||
tree create_mem_ref (gimple_stmt_iterator *, tree, tree,
|
||||
struct affine_tree_combination *, tree, bool);
|
||||
rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool);
|
||||
void get_address_description (tree, struct mem_address *);
|
||||
|
|
|
@ -338,7 +338,7 @@ valid_mem_ref_p (enum machine_mode mode, addr_space_t as,
|
|||
TARGET_MEM_REF. */
|
||||
|
||||
static tree
|
||||
create_mem_ref_raw (tree type, struct mem_address *addr)
|
||||
create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr)
|
||||
{
|
||||
if (!valid_mem_ref_p (TYPE_MODE (type), TYPE_ADDR_SPACE (type), addr))
|
||||
return NULL_TREE;
|
||||
|
@ -349,6 +349,24 @@ create_mem_ref_raw (tree type, struct mem_address *addr)
|
|||
if (addr->offset && integer_zerop (addr->offset))
|
||||
addr->offset = NULL_TREE;
|
||||
|
||||
/* If possible use a plain MEM_REF instead of a TARGET_MEM_REF. */
|
||||
if (alias_ptr_type
|
||||
&& !addr->index
|
||||
&& !addr->step)
|
||||
{
|
||||
tree base, offset;
|
||||
gcc_assert (!addr->symbol ^ !addr->base);
|
||||
if (addr->symbol)
|
||||
base = build_fold_addr_expr (addr->symbol);
|
||||
else
|
||||
base = addr->base;
|
||||
if (addr->offset)
|
||||
offset = fold_convert (alias_ptr_type, addr->offset);
|
||||
else
|
||||
offset = build_int_cst (alias_ptr_type, 0);
|
||||
return fold_build2 (MEM_REF, type, base, offset);
|
||||
}
|
||||
|
||||
return build6 (TARGET_MEM_REF, type,
|
||||
addr->symbol, addr->base, addr->index,
|
||||
addr->step, addr->offset, NULL);
|
||||
|
@ -628,8 +646,8 @@ gimplify_mem_ref_parts (gimple_stmt_iterator *gsi, struct mem_address *parts)
|
|||
of created memory reference. */
|
||||
|
||||
tree
|
||||
create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
|
||||
tree base_hint, bool speed)
|
||||
create_mem_ref (gimple_stmt_iterator *gsi, tree type, tree alias_ptr_type,
|
||||
aff_tree *addr, tree base_hint, bool speed)
|
||||
{
|
||||
tree mem_ref, tmp;
|
||||
tree atype;
|
||||
|
@ -637,7 +655,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
|
|||
|
||||
addr_to_parts (type, addr, base_hint, &parts, speed);
|
||||
gimplify_mem_ref_parts (gsi, &parts);
|
||||
mem_ref = create_mem_ref_raw (type, &parts);
|
||||
mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts);
|
||||
if (mem_ref)
|
||||
return mem_ref;
|
||||
|
||||
|
@ -653,7 +671,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
|
|||
true, NULL_TREE, true, GSI_SAME_STMT);
|
||||
parts.step = NULL_TREE;
|
||||
|
||||
mem_ref = create_mem_ref_raw (type, &parts);
|
||||
mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts);
|
||||
if (mem_ref)
|
||||
return mem_ref;
|
||||
}
|
||||
|
@ -688,7 +706,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
|
|||
parts.base = tmp;
|
||||
parts.symbol = NULL_TREE;
|
||||
|
||||
mem_ref = create_mem_ref_raw (type, &parts);
|
||||
mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts);
|
||||
if (mem_ref)
|
||||
return mem_ref;
|
||||
}
|
||||
|
@ -709,7 +727,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
|
|||
parts.base = parts.index;
|
||||
parts.index = NULL_TREE;
|
||||
|
||||
mem_ref = create_mem_ref_raw (type, &parts);
|
||||
mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts);
|
||||
if (mem_ref)
|
||||
return mem_ref;
|
||||
}
|
||||
|
@ -731,7 +749,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
|
|||
|
||||
parts.offset = NULL_TREE;
|
||||
|
||||
mem_ref = create_mem_ref_raw (type, &parts);
|
||||
mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts);
|
||||
if (mem_ref)
|
||||
return mem_ref;
|
||||
}
|
||||
|
@ -819,7 +837,7 @@ maybe_fold_tmr (tree ref)
|
|||
if (!changed)
|
||||
return NULL_TREE;
|
||||
|
||||
ret = create_mem_ref_raw (TREE_TYPE (ref), &addr);
|
||||
ret = create_mem_ref_raw (TREE_TYPE (ref), NULL_TREE, &addr);
|
||||
if (!ret)
|
||||
return NULL_TREE;
|
||||
|
||||
|
|
|
@ -5547,33 +5547,41 @@ unshare_and_remove_ssa_names (tree ref)
|
|||
static void
|
||||
copy_ref_info (tree new_ref, tree old_ref)
|
||||
{
|
||||
if (TREE_CODE (old_ref) == TARGET_MEM_REF)
|
||||
copy_mem_ref_info (new_ref, old_ref);
|
||||
else
|
||||
tree new_ptr_base = NULL_TREE;
|
||||
|
||||
if (TREE_CODE (old_ref) == TARGET_MEM_REF
|
||||
&& TREE_CODE (new_ref) == TARGET_MEM_REF)
|
||||
TMR_ORIGINAL (new_ref) = TMR_ORIGINAL (old_ref);
|
||||
else if (TREE_CODE (new_ref) == TARGET_MEM_REF)
|
||||
TMR_ORIGINAL (new_ref) = unshare_and_remove_ssa_names (old_ref);
|
||||
|
||||
TREE_SIDE_EFFECTS (new_ref) = TREE_SIDE_EFFECTS (old_ref);
|
||||
TREE_THIS_VOLATILE (new_ref) = TREE_THIS_VOLATILE (old_ref);
|
||||
|
||||
if (TREE_CODE (new_ref) == TARGET_MEM_REF)
|
||||
new_ptr_base = TMR_BASE (new_ref);
|
||||
else if (TREE_CODE (new_ref) == MEM_REF)
|
||||
new_ptr_base = TREE_OPERAND (new_ref, 0);
|
||||
|
||||
/* We can transfer points-to information from an old pointer
|
||||
or decl base to the new one. */
|
||||
if (new_ptr_base
|
||||
&& TREE_CODE (new_ptr_base) == SSA_NAME
|
||||
&& POINTER_TYPE_P (TREE_TYPE (new_ptr_base))
|
||||
&& !SSA_NAME_PTR_INFO (new_ptr_base))
|
||||
{
|
||||
TMR_ORIGINAL (new_ref) = unshare_and_remove_ssa_names (old_ref);
|
||||
TREE_SIDE_EFFECTS (new_ref) = TREE_SIDE_EFFECTS (old_ref);
|
||||
TREE_THIS_VOLATILE (new_ref) = TREE_THIS_VOLATILE (old_ref);
|
||||
/* We can transfer points-to information from an old pointer
|
||||
or decl base to the new one. */
|
||||
if (TMR_BASE (new_ref)
|
||||
&& TREE_CODE (TMR_BASE (new_ref)) == SSA_NAME
|
||||
&& POINTER_TYPE_P (TREE_TYPE (TMR_BASE (new_ref)))
|
||||
&& !SSA_NAME_PTR_INFO (TMR_BASE (new_ref)))
|
||||
tree base = get_base_address (old_ref);
|
||||
if ((INDIRECT_REF_P (base)
|
||||
|| TREE_CODE (base) == MEM_REF)
|
||||
&& TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
|
||||
duplicate_ssa_name_ptr_info
|
||||
(new_ptr_base, SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)));
|
||||
else if (TREE_CODE (base) == VAR_DECL
|
||||
|| TREE_CODE (base) == PARM_DECL
|
||||
|| TREE_CODE (base) == RESULT_DECL)
|
||||
{
|
||||
tree base = get_base_address (old_ref);
|
||||
if ((INDIRECT_REF_P (base)
|
||||
|| TREE_CODE (base) == MEM_REF)
|
||||
&& TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
|
||||
duplicate_ssa_name_ptr_info
|
||||
(TMR_BASE (new_ref), SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)));
|
||||
else if (TREE_CODE (base) == VAR_DECL
|
||||
|| TREE_CODE (base) == PARM_DECL
|
||||
|| TREE_CODE (base) == RESULT_DECL)
|
||||
{
|
||||
struct ptr_info_def *pi = get_ptr_info (TMR_BASE (new_ref));
|
||||
pt_solution_set_var (&pi->pt, base);
|
||||
}
|
||||
struct ptr_info_def *pi = get_ptr_info (new_ptr_base);
|
||||
pt_solution_set_var (&pi->pt, base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5608,8 +5616,9 @@ rewrite_use_address (struct ivopts_data *data,
|
|||
if (cand->iv->base_object)
|
||||
base_hint = var_at_stmt (data->current_loop, cand, use->stmt);
|
||||
|
||||
ref = create_mem_ref (&bsi, TREE_TYPE (*use->op_p), &aff, base_hint,
|
||||
data->speed);
|
||||
ref = create_mem_ref (&bsi, TREE_TYPE (*use->op_p),
|
||||
reference_alias_ptr_type (*use->op_p),
|
||||
&aff, base_hint, data->speed);
|
||||
copy_ref_info (ref, *use->op_p);
|
||||
*use->op_p = ref;
|
||||
}
|
||||
|
|
19
gcc/tree.c
19
gcc/tree.c
|
@ -3913,6 +3913,25 @@ mem_ref_offset (const_tree t)
|
|||
TYPE_PRECISION (TREE_TYPE (toff)));
|
||||
}
|
||||
|
||||
/* Return the pointer-type relevant for TBAA purposes from the
|
||||
gimple memory reference tree T. This is the type to be used for
|
||||
the offset operand of MEM_REF or TARGET_MEM_REF replacements of T. */
|
||||
|
||||
tree
|
||||
reference_alias_ptr_type (const_tree t)
|
||||
{
|
||||
const_tree base = t;
|
||||
while (handled_component_p (base))
|
||||
base = TREE_OPERAND (base, 0);
|
||||
if (TREE_CODE (base) == MEM_REF)
|
||||
return TREE_TYPE (TREE_OPERAND (base, 1));
|
||||
else if (TREE_CODE (base) == TARGET_MEM_REF
|
||||
|| TREE_CODE (base) == MISALIGNED_INDIRECT_REF)
|
||||
return NULL_TREE;
|
||||
else
|
||||
return build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (base)));
|
||||
}
|
||||
|
||||
/* Similar except don't specify the TREE_TYPE
|
||||
and leave the TREE_SIDE_EFFECTS as 0.
|
||||
It is permissible for arguments to be null,
|
||||
|
|
|
@ -4965,6 +4965,7 @@ extern tree build_simple_mem_ref_loc (location_t, tree);
|
|||
#define build_simple_mem_ref(T)\
|
||||
build_simple_mem_ref_loc (UNKNOWN_LOCATION, T)
|
||||
extern double_int mem_ref_offset (const_tree);
|
||||
extern tree reference_alias_ptr_type (const_tree);
|
||||
extern tree constant_boolean_node (int, tree);
|
||||
extern tree div_if_zero_remainder (enum tree_code, const_tree, const_tree);
|
||||
|
||||
|
|
Loading…
Reference in New Issue