tree-ssa-structalias.c (could_have_pointers): Tidy.

* 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.


testsuite/ChangeLog

	* gcc.dg/tree-ssa/20070302-1.c: New test.

From-SVN: r122484
This commit is contained in:
Diego Novillo 2007-03-02 19:20:14 +00:00 committed by Diego Novillo
parent 0618281a42
commit 6e7e772dce
5 changed files with 114 additions and 27 deletions

View File

@ -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> 2007-03-02 Eric Botcazou <ebotcazou@adacore.com>
* config/alpha/alpha.c (alpha_gp_save_rtx): Insert the insns at the * config/alpha/alpha.c (alpha_gp_save_rtx): Insert the insns at the

View File

@ -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> 2007-03-02 Joseph Myers <joseph@codesourcery.com>
* gcc.target/powerpc/spe-unwind-1.c, g++.dg/eh/simd-5.C: New * gcc.target/powerpc/spe-unwind-1.c, g++.dg/eh/simd-5.C: New

View File

@ -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);
}

View File

@ -142,6 +142,7 @@ static VEC(tree,heap) *build_vuses;
/* Bitmap obstack for our datastructures that needs to survive across /* Bitmap obstack for our datastructures that needs to survive across
compilations of multiple functions. */ compilations of multiple functions. */
static bitmap_obstack operands_bitmap_obstack; static bitmap_obstack operands_bitmap_obstack;
/* Set for building all the loaded symbols. */ /* Set for building all the loaded symbols. */
static bitmap build_loads; 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 get_expr_operands. FULL_REF is a tree that contains the entire
pointer dereference expression, if available, or NULL otherwise. pointer dereference expression, if available, or NULL otherwise.
OFFSET and SIZE come from the memory access expression that 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 static void
add_virtual_operand (tree var, stmt_ann_t s_ann, int flags, add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
tree full_ref, HOST_WIDE_INT offset, tree full_ref, HOST_WIDE_INT offset,
HOST_WIDE_INT size) HOST_WIDE_INT size, bool is_call_site)
{ {
bitmap aliases = NULL; bitmap aliases = NULL;
tree sym; tree sym;
@ -1480,10 +1482,12 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
if (MTAG_P (var)) if (MTAG_P (var))
aliases = MTAG_ALIASES (var); aliases = MTAG_ALIASES (var);
if (aliases == NULL) if (aliases == NULL)
{ {
if (s_ann && !gimple_aliases_computed_p (cfun)) if (s_ann && !gimple_aliases_computed_p (cfun))
s_ann->has_volatile_ops = true; s_ann->has_volatile_ops = true;
/* The variable is not aliased or it is an alias tag. */ /* The variable is not aliased or it is an alias tag. */
if (flags & opf_def) if (flags & opf_def)
append_vdef (var); append_vdef (var);
@ -1508,7 +1512,13 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
al = referenced_var (i); al = referenced_var (i);
if (!access_can_touch_variable (full_ref, al, offset, size)) if (!access_can_touch_variable (full_ref, al, offset, size))
continue; 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; none_added = false;
append_vdef (al); append_vdef (al);
} }
@ -1529,6 +1539,13 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
al = referenced_var (i); al = referenced_var (i);
if (!access_can_touch_variable (full_ref, al, offset, size)) if (!access_can_touch_variable (full_ref, al, offset, size))
continue; 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; none_added = false;
append_vuse (al); append_vuse (al);
} }
@ -1575,7 +1592,7 @@ add_stmt_operand (tree *var_p, stmt_ann_t s_ann, int flags)
append_use (var_p); append_use (var_p);
} }
else 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. */ /* PTR has its own memory tag. Use it. */
add_virtual_operand (pi->name_mem_tag, s_ann, flags, add_virtual_operand (pi->name_mem_tag, s_ann, flags,
full_ref, offset, size); full_ref, offset, size, false);
} }
else else
{ {
@ -1651,10 +1668,12 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags,
if (v_ann->symbol_mem_tag) if (v_ann->symbol_mem_tag)
add_virtual_operand (v_ann->symbol_mem_tag, s_ann, flags, add_virtual_operand (v_ann->symbol_mem_tag, s_ann, flags,
full_ref, offset, size); full_ref, offset, size, false);
/* Aliasing information is missing; mark statement as volatile so we
won't optimize it out too actively. */ /* Aliasing information is missing; mark statement as
else if (s_ann && !gimple_aliases_computed_p (cfun) volatile so we won't optimize it out too actively. */
else if (s_ann
&& !gimple_aliases_computed_p (cfun)
&& (flags & opf_def)) && (flags & opf_def))
s_ann->has_volatile_ops = true; s_ann->has_volatile_ops = true;
} }
@ -1743,12 +1762,11 @@ add_call_clobber_ops (tree stmt, tree callee)
if (s_ann) if (s_ann)
s_ann->makes_clobbering_call = true; s_ann->makes_clobbering_call = true;
/* If we created .GLOBAL_VAR earlier, just use it. See compute_may_aliases /* If we created .GLOBAL_VAR earlier, just use it. */
for the heuristic used to decide whether to create .GLOBAL_VAR or not. */
if (gimple_global_var (cfun)) if (gimple_global_var (cfun))
{ {
tree var = 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; return;
} }
@ -1772,10 +1790,13 @@ add_call_clobber_ops (tree stmt, tree callee)
if (TREE_CODE (var) == STRUCT_FIELD_TAG) if (TREE_CODE (var) == STRUCT_FIELD_TAG)
real_var = SFT_PARENT_VAR (var); real_var = SFT_PARENT_VAR (var);
not_read = not_read_b ? bitmap_bit_p (not_read_b, not_read = not_read_b
DECL_UID (real_var)) : false; ? bitmap_bit_p (not_read_b, DECL_UID (real_var))
not_written = not_written_b ? bitmap_bit_p (not_written_b, : false;
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)); gcc_assert (!unmodifiable_var_p (var));
clobber_stats.clobbered_vars++; clobber_stats.clobbered_vars++;
@ -1789,7 +1810,7 @@ add_call_clobber_ops (tree stmt, tree callee)
tree call = get_call_expr_in (stmt); tree call = get_call_expr_in (stmt);
if (call_expr_flags (call) & (ECF_CONST | ECF_PURE)) 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++; clobber_stats.unescapable_clobbers_avoided++;
continue; continue;
} }
@ -1804,12 +1825,12 @@ add_call_clobber_ops (tree stmt, tree callee)
{ {
clobber_stats.static_write_clobbers_avoided++; clobber_stats.static_write_clobbers_avoided++;
if (!not_read) if (!not_read)
add_stmt_operand (&var, s_ann, opf_use); add_virtual_operand (var, s_ann, opf_use, NULL, 0, -1, true);
else else
clobber_stats.static_read_clobbers_avoided++; clobber_stats.static_read_clobbers_avoided++;
} }
else 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)) if (gimple_global_var (cfun))
{ {
tree var = 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; return;
} }
@ -1861,7 +1882,7 @@ add_call_read_ops (tree stmt, tree callee)
continue; continue;
} }
add_stmt_operand (&var, s_ann, opf_use | opf_implicit); add_virtual_operand (var, s_ann, opf_use, NULL, 0, -1, true);
} }
} }

View File

@ -2312,9 +2312,11 @@ could_have_pointers (tree t)
{ {
tree type = TREE_TYPE (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) || TREE_CODE (type) == COMPLEX_TYPE)
return true; return true;
return false; return false;
} }
@ -2524,6 +2526,7 @@ get_constraint_for (tree t, VEC (ce_s, heap) **results)
tree pttype = TREE_TYPE (TREE_TYPE (t)); tree pttype = TREE_TYPE (TREE_TYPE (t));
get_constraint_for (exp, results); get_constraint_for (exp, results);
/* Make sure we capture constraints to all elements /* Make sure we capture constraints to all elements
of an array. */ of an array. */
if ((handled_component_p (exp) 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 /* Update related alias information kept in AI. This is used when
building name tags, alias sets and deciding grouping heuristics. building name tags, alias sets and deciding grouping heuristics.
STMT is the statement to process. This function also updates 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 /* In IPA mode, we need to generate constraints to pass call
arguments through their calls. There are two case, either a arguments through their calls. There are two cases, either a
modify_expr when we are returning a value, or just a plain GIMPLE_MODIFY_STMT when we are returning a value, or just a plain
call_expr when we are not. */ CALL_EXPR when we are not. */
else if (in_ipa_mode else if (in_ipa_mode
&& ((TREE_CODE (t) == GIMPLE_MODIFY_STMT && ((TREE_CODE (t) == GIMPLE_MODIFY_STMT
&& TREE_CODE (GIMPLE_STMT_OPERAND (t, 1)) == CALL_EXPR && TREE_CODE (GIMPLE_STMT_OPERAND (t, 1)) == CALL_EXPR
@ -3399,6 +3403,7 @@ find_func_aliases (tree origt)
} }
i++; i++;
} }
/* If we are returning a value, assign it to the result. */ /* If we are returning a value, assign it to the result. */
if (lhsop) if (lhsop)
{ {
@ -4099,8 +4104,8 @@ intra_create_variable_infos (void)
tree t; tree t;
struct constraint_expr lhs, rhs; struct constraint_expr lhs, rhs;
/* For each incoming pointer argument arg, ARG = ANYTHING or a /* For each incoming pointer argument arg, create the constraint ARG
dummy variable if flag_argument_noalias > 2. */ = ANYTHING or a dummy variable if flag_argument_noalias is set. */
for (t = DECL_ARGUMENTS (current_function_decl); t; t = TREE_CHAIN (t)) for (t = DECL_ARGUMENTS (current_function_decl); t; t = TREE_CHAIN (t))
{ {
varinfo_t p; varinfo_t p;