summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20070302-1.c44
-rw-r--r--gcc/tree-ssa-operands.c63
-rw-r--r--gcc/tree-ssa-structalias.c17
5 files changed, 114 insertions, 27 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 58d89ae689e..0bc6279a430 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2007-03-02 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-structalias.c (could_have_pointers): Tidy.
+ (get_constraint_for): Likewise.
+ (do_structure_copy): Likewise.
+ (find_func_aliases): Fix references to MODIFY_EXPR.
+ (intra_create_variable_infos): Tidy.
+ * tree-ssa-operands.c (add_virtual_operand): Add argument
+ IS_CALL_SITE.
+ When adding members of alias sets, if IS_CALL_SITE is true and
+ the symbol is not call-clobbered, skip it.
+ Adjust all callers.
+
2007-03-02 Eric Botcazou <ebotcazou@adacore.com>
* config/alpha/alpha.c (alpha_gp_save_rtx): Insert the insns at the
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3247f94b119..88677236c68 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2007-03-02 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20070302-1.c: New test.
+
2007-03-02 Joseph Myers <joseph@codesourcery.com>
* gcc.target/powerpc/spe-unwind-1.c, g++.dg/eh/simd-5.C: New
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20070302-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20070302-1.c
new file mode 100644
index 00000000000..17fcbab2580
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20070302-1.c
@@ -0,0 +1,44 @@
+/* { dg-do link } */
+/* { dg-options "-O2" } */
+
+struct A
+{
+ int x;
+ float y;
+};
+
+volatile float X, Y;
+
+int baz (struct A *z, struct A *y)
+{
+ z->x = (int) X;
+ z->y = Y;
+ y->x = (int) X;
+ y->y = Y;
+}
+
+
+struct A B;
+
+float foo (int i)
+{
+ struct A *p, x, y, z;
+
+ p = (i > 10) ? &x : &z;
+ x.y = 3.0;
+ p->x += baz (&z, &y);
+ X = z.y;
+ Y = p->y;
+
+ /* This predicate should always evaluate to false. The call to
+ baz() is not a clobbering site for x.y. The operand scanner was
+ considering it a clobbering site for x.y because x.y is in the
+ alias set of a call-clobbered memory tag. */
+ if (x.y != 3.0)
+ link_error ();
+}
+
+main(int argc, char **argv)
+{
+ foo (argc);
+}
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index be9cd6b9a24..8e8ef6413f5 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -142,6 +142,7 @@ static VEC(tree,heap) *build_vuses;
/* Bitmap obstack for our datastructures that needs to survive across
compilations of multiple functions. */
static bitmap_obstack operands_bitmap_obstack;
+
/* Set for building all the loaded symbols. */
static bitmap build_loads;
@@ -1433,12 +1434,13 @@ access_can_touch_variable (tree ref, tree alias, HOST_WIDE_INT offset,
get_expr_operands. FULL_REF is a tree that contains the entire
pointer dereference expression, if available, or NULL otherwise.
OFFSET and SIZE come from the memory access expression that
- generated this virtual operand. */
+ generated this virtual operand. IS_CALL_SITE is true if the
+ affected statement is a call site. */
static void
add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
tree full_ref, HOST_WIDE_INT offset,
- HOST_WIDE_INT size)
+ HOST_WIDE_INT size, bool is_call_site)
{
bitmap aliases = NULL;
tree sym;
@@ -1480,10 +1482,12 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
if (MTAG_P (var))
aliases = MTAG_ALIASES (var);
+
if (aliases == NULL)
{
if (s_ann && !gimple_aliases_computed_p (cfun))
s_ann->has_volatile_ops = true;
+
/* The variable is not aliased or it is an alias tag. */
if (flags & opf_def)
append_vdef (var);
@@ -1508,7 +1512,13 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
al = referenced_var (i);
if (!access_can_touch_variable (full_ref, al, offset, size))
continue;
-
+
+ /* Call-clobbered tags may have non-call-clobbered
+ symbols in their alias sets. Ignore them if we are
+ adding VOPs for a call site. */
+ if (is_call_site && !is_call_clobbered (al))
+ continue;
+
none_added = false;
append_vdef (al);
}
@@ -1529,6 +1539,13 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
al = referenced_var (i);
if (!access_can_touch_variable (full_ref, al, offset, size))
continue;
+
+ /* Call-clobbered tags may have non-call-clobbered
+ symbols in their alias sets. Ignore them if we are
+ adding VOPs for a call site. */
+ if (is_call_site && !is_call_clobbered (al))
+ continue;
+
none_added = false;
append_vuse (al);
}
@@ -1575,7 +1592,7 @@ add_stmt_operand (tree *var_p, stmt_ann_t s_ann, int flags)
append_use (var_p);
}
else
- add_virtual_operand (var, s_ann, flags, NULL_TREE, 0, -1);
+ add_virtual_operand (var, s_ann, flags, NULL_TREE, 0, -1, false);
}
@@ -1622,7 +1639,7 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags,
{
/* PTR has its own memory tag. Use it. */
add_virtual_operand (pi->name_mem_tag, s_ann, flags,
- full_ref, offset, size);
+ full_ref, offset, size, false);
}
else
{
@@ -1651,10 +1668,12 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags,
if (v_ann->symbol_mem_tag)
add_virtual_operand (v_ann->symbol_mem_tag, s_ann, flags,
- full_ref, offset, size);
- /* Aliasing information is missing; mark statement as volatile so we
- won't optimize it out too actively. */
- else if (s_ann && !gimple_aliases_computed_p (cfun)
+ full_ref, offset, size, false);
+
+ /* Aliasing information is missing; mark statement as
+ volatile so we won't optimize it out too actively. */
+ else if (s_ann
+ && !gimple_aliases_computed_p (cfun)
&& (flags & opf_def))
s_ann->has_volatile_ops = true;
}
@@ -1743,12 +1762,11 @@ add_call_clobber_ops (tree stmt, tree callee)
if (s_ann)
s_ann->makes_clobbering_call = true;
- /* If we created .GLOBAL_VAR earlier, just use it. See compute_may_aliases
- for the heuristic used to decide whether to create .GLOBAL_VAR or not. */
+ /* If we created .GLOBAL_VAR earlier, just use it. */
if (gimple_global_var (cfun))
{
tree var = gimple_global_var (cfun);
- add_stmt_operand (&var, s_ann, opf_def);
+ add_virtual_operand (var, s_ann, opf_def, NULL, 0, -1, true);
return;
}
@@ -1772,10 +1790,13 @@ add_call_clobber_ops (tree stmt, tree callee)
if (TREE_CODE (var) == STRUCT_FIELD_TAG)
real_var = SFT_PARENT_VAR (var);
- not_read = not_read_b ? bitmap_bit_p (not_read_b,
- DECL_UID (real_var)) : false;
- not_written = not_written_b ? bitmap_bit_p (not_written_b,
- DECL_UID (real_var)) : false;
+ not_read = not_read_b
+ ? bitmap_bit_p (not_read_b, DECL_UID (real_var))
+ : false;
+
+ not_written = not_written_b
+ ? bitmap_bit_p (not_written_b, DECL_UID (real_var))
+ : false;
gcc_assert (!unmodifiable_var_p (var));
clobber_stats.clobbered_vars++;
@@ -1789,7 +1810,7 @@ add_call_clobber_ops (tree stmt, tree callee)
tree call = get_call_expr_in (stmt);
if (call_expr_flags (call) & (ECF_CONST | ECF_PURE))
{
- add_stmt_operand (&var, s_ann, opf_use);
+ add_virtual_operand (var, s_ann, opf_use, NULL, 0, -1, true);
clobber_stats.unescapable_clobbers_avoided++;
continue;
}
@@ -1804,12 +1825,12 @@ add_call_clobber_ops (tree stmt, tree callee)
{
clobber_stats.static_write_clobbers_avoided++;
if (!not_read)
- add_stmt_operand (&var, s_ann, opf_use);
+ add_virtual_operand (var, s_ann, opf_use, NULL, 0, -1, true);
else
clobber_stats.static_read_clobbers_avoided++;
}
else
- add_virtual_operand (var, s_ann, opf_def, NULL, 0, -1);
+ add_virtual_operand (var, s_ann, opf_def, NULL, 0, -1, true);
}
}
@@ -1831,7 +1852,7 @@ add_call_read_ops (tree stmt, tree callee)
if (gimple_global_var (cfun))
{
tree var = gimple_global_var (cfun);
- add_stmt_operand (&var, s_ann, opf_use);
+ add_virtual_operand (var, s_ann, opf_use, NULL, 0, -1, true);
return;
}
@@ -1861,7 +1882,7 @@ add_call_read_ops (tree stmt, tree callee)
continue;
}
- add_stmt_operand (&var, s_ann, opf_use | opf_implicit);
+ add_virtual_operand (var, s_ann, opf_use, NULL, 0, -1, true);
}
}
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index f031bf0102f..fc5bee8a920 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -2312,9 +2312,11 @@ could_have_pointers (tree t)
{
tree type = TREE_TYPE (t);
- if (POINTER_TYPE_P (type) || AGGREGATE_TYPE_P (type)
+ if (POINTER_TYPE_P (type)
+ || AGGREGATE_TYPE_P (type)
|| TREE_CODE (type) == COMPLEX_TYPE)
return true;
+
return false;
}
@@ -2524,6 +2526,7 @@ get_constraint_for (tree t, VEC (ce_s, heap) **results)
tree pttype = TREE_TYPE (TREE_TYPE (t));
get_constraint_for (exp, results);
+
/* Make sure we capture constraints to all elements
of an array. */
if ((handled_component_p (exp)
@@ -3001,6 +3004,7 @@ do_structure_copy (tree lhsop, tree rhsop)
}
}
+
/* Update related alias information kept in AI. This is used when
building name tags, alias sets and deciding grouping heuristics.
STMT is the statement to process. This function also updates
@@ -3326,9 +3330,9 @@ find_func_aliases (tree origt)
}
}
/* In IPA mode, we need to generate constraints to pass call
- arguments through their calls. There are two case, either a
- modify_expr when we are returning a value, or just a plain
- call_expr when we are not. */
+ arguments through their calls. There are two cases, either a
+ GIMPLE_MODIFY_STMT when we are returning a value, or just a plain
+ CALL_EXPR when we are not. */
else if (in_ipa_mode
&& ((TREE_CODE (t) == GIMPLE_MODIFY_STMT
&& TREE_CODE (GIMPLE_STMT_OPERAND (t, 1)) == CALL_EXPR
@@ -3399,6 +3403,7 @@ find_func_aliases (tree origt)
}
i++;
}
+
/* If we are returning a value, assign it to the result. */
if (lhsop)
{
@@ -4099,8 +4104,8 @@ intra_create_variable_infos (void)
tree t;
struct constraint_expr lhs, rhs;
- /* For each incoming pointer argument arg, ARG = ANYTHING or a
- dummy variable if flag_argument_noalias > 2. */
+ /* For each incoming pointer argument arg, create the constraint ARG
+ = ANYTHING or a dummy variable if flag_argument_noalias is set. */
for (t = DECL_ARGUMENTS (current_function_decl); t; t = TREE_CHAIN (t))
{
varinfo_t p;