aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/ipa-prop.c15
-rw-r--r--gcc/ipa-prop.h4
-rw-r--r--gcc/tree-sra.c6
4 files changed, 24 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 47e2b866ef2..7c380d35f03 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
2010-12-09 Martin Jambor <mjambor@suse.cz>
+ * ipa-prop.h (struct ipa_parm_adjustment): New field alias_ptr_type.
+ * ipa-prop.c (ipa_modify_call_arguments): Use it.
+ * tree-sra.c (splice_param_accesses): Test that all accesses have the
+ same alias reference type.
+ (turn_representatives_into_adjustments): Set alias_ptr_type of the
+ adjustment.
+
+2010-12-09 Martin Jambor <mjambor@suse.cz>
+
PR middle-end/46734
* tree-sra.c (splice_param_accesses): Check that there are not
multiple ADDRESSABLE types.
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 7c7df56e6f4..0e5a4b19d18 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -2210,13 +2210,10 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
base = gimple_call_arg (stmt, adj->base_index);
loc = EXPR_LOCATION (base);
- if (TREE_CODE (base) == ADDR_EXPR
- && DECL_P (TREE_OPERAND (base, 0)))
- off = build_int_cst (TREE_TYPE (base),
+ if (TREE_CODE (base) != ADDR_EXPR
+ && POINTER_TYPE_P (TREE_TYPE (base)))
+ off = build_int_cst (adj->alias_ptr_type,
adj->offset / BITS_PER_UNIT);
- else if (TREE_CODE (base) != ADDR_EXPR
- && POINTER_TYPE_P (TREE_TYPE (base)))
- off = build_int_cst (TREE_TYPE (base), adj->offset / BITS_PER_UNIT);
else
{
HOST_WIDE_INT base_offset;
@@ -2230,12 +2227,12 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
if (!base)
{
base = build_fold_addr_expr (prev_base);
- off = build_int_cst (reference_alias_ptr_type (prev_base),
+ off = build_int_cst (adj->alias_ptr_type,
adj->offset / BITS_PER_UNIT);
}
else if (TREE_CODE (base) == MEM_REF)
{
- off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
+ off = build_int_cst (adj->alias_ptr_type,
base_offset
+ adj->offset / BITS_PER_UNIT);
off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1),
@@ -2244,7 +2241,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
}
else
{
- off = build_int_cst (reference_alias_ptr_type (prev_base),
+ off = build_int_cst (adj->alias_ptr_type,
base_offset
+ adj->offset / BITS_PER_UNIT);
base = build_fold_addr_expr (base);
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 40f7ef950c4..fdf1a5e4a99 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -458,6 +458,10 @@ struct ipa_parm_adjustment
be a pointer to this type. */
tree type;
+ /* Alias refrerence type to be used in MEM_REFs when adjusting caller
+ arguments. */
+ tree alias_ptr_type;
+
/* The new declaration when creating/replacing a parameter. Created by
ipa_modify_formal_parameters, useful for functions modifying the body
accordingly. */
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 4330a17fc49..9d22ad76b4a 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -3563,10 +3563,12 @@ splice_param_accesses (tree parm, bool *ro_grp)
while (i < access_count)
{
bool modification;
+ tree a1_alias_type;
access = VEC_index (access_p, access_vec, i);
modification = access->write;
if (access_precludes_ipa_sra_p (access))
return NULL;
+ a1_alias_type = reference_alias_ptr_type (access->expr);
/* Access is about to become group representative unless we find some
nasty overlap which would preclude us from breaking this parameter
@@ -3590,7 +3592,8 @@ splice_param_accesses (tree parm, bool *ro_grp)
if (access_precludes_ipa_sra_p (ac2)
|| (ac2->type != access->type
&& (TREE_ADDRESSABLE (ac2->type)
- || TREE_ADDRESSABLE (access->type))))
+ || TREE_ADDRESSABLE (access->type)))
+ || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
return NULL;
modification |= ac2->write;
@@ -3825,6 +3828,7 @@ turn_representatives_into_adjustments (VEC (access_p, heap) *representatives,
adj->base_index = index;
adj->base = repr->base;
adj->type = repr->type;
+ adj->alias_ptr_type = reference_alias_ptr_type (repr->expr);
adj->offset = repr->offset;
adj->by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
&& (repr->grp_maybe_modified