From 6e7e772dceb2f238c2645ad4c695787fd69d381d Mon Sep 17 00:00:00 2001 From: Diego Novillo Date: Fri, 2 Mar 2007 19:20:14 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 13 +++++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/tree-ssa/20070302-1.c | 44 +++++++++++++++ gcc/tree-ssa-operands.c | 63 ++++++++++++++-------- gcc/tree-ssa-structalias.c | 17 +++--- 5 files changed, 114 insertions(+), 27 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/20070302-1.c 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 + + * 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 * 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 + + * gcc.dg/tree-ssa/20070302-1.c: New test. + 2007-03-02 Joseph Myers * 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;