diff options
author | Michael Matz <matz@suse.de> | 2009-10-26 13:00:36 +0000 |
---|---|---|
committer | Michael Matz <matz@gcc.gnu.org> | 2009-10-26 13:00:36 +0000 |
commit | 842809179e1d2fbf0a2af44e6e3f445770613bc6 (patch) | |
tree | fbb6277956a1693b32bea61a71c9fbf0f2321aee /gcc/tree-ssa-pre.c | |
parent | bd02b3a0c9223cecb7ec0367ecae6c76bbcd9b50 (diff) | |
download | gcc-842809179e1d2fbf0a2af44e6e3f445770613bc6.zip gcc-842809179e1d2fbf0a2af44e6e3f445770613bc6.tar.gz gcc-842809179e1d2fbf0a2af44e6e3f445770613bc6.tar.bz2 |
re PR tree-optimization/41783 (r151561 (PRE fix) regresses zeusmp)
PR tree-optimization/41783
* tree-ssa-alias.c (get_continuation_for_phi): Export, add a special
case for simple diamonds
* tree-ssa-alias.h (get_continuation_for_phi): Declare.
* tree-ssa-pre.c (translate_vuse_through_block): Add same_valid
argument, use alias oracle to skip some vdefs.
(phi_translate_1): Change call to above, don't allocate new
value ids if they can stay the same.
(compute_avail): Allow vuse walking when looking up references.
testsuite/
* gcc.dg/pr41783.c: New test.
* gcc.dg/tree-ssa/ssa-pre-23.c: Adjust.
* gcc.dg/tree-ssa/ssa-pre-24.c: Don't xfail anymore.
* gcc.dg/tree-ssa/ssa-pre-27.c: New test.
From-SVN: r153551
Diffstat (limited to 'gcc/tree-ssa-pre.c')
-rw-r--r-- | gcc/tree-ssa-pre.c | 89 |
1 files changed, 63 insertions, 26 deletions
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 6ae05b5..2ef6d76 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -1243,43 +1243,74 @@ do_unary: } /* Translate the VUSE backwards through phi nodes in PHIBLOCK, so that - it has the value it would have in BLOCK. */ + it has the value it would have in BLOCK. Set *SAME_VALID to true + in case the new vuse doesn't change the value id of the OPERANDS. */ static tree translate_vuse_through_block (VEC (vn_reference_op_s, heap) *operands, alias_set_type set, tree type, tree vuse, basic_block phiblock, - basic_block block) + basic_block block, bool *same_valid) { gimple phi = SSA_NAME_DEF_STMT (vuse); ao_ref ref; + edge e = NULL; + bool use_oracle; + + *same_valid = true; if (gimple_bb (phi) != phiblock) return vuse; - if (gimple_code (phi) == GIMPLE_PHI) - { - edge e = find_edge (block, phiblock); - return PHI_ARG_DEF (phi, e->dest_idx); - } - - if (!ao_ref_init_from_vn_reference (&ref, set, type, operands)) - return NULL_TREE; + use_oracle = ao_ref_init_from_vn_reference (&ref, set, type, operands); /* Use the alias-oracle to find either the PHI node in this block, the first VUSE used in this block that is equivalent to vuse or the first VUSE which definition in this block kills the value. */ - while (!stmt_may_clobber_ref_p_1 (phi, &ref)) + if (gimple_code (phi) == GIMPLE_PHI) + e = find_edge (block, phiblock); + else if (use_oracle) + while (!stmt_may_clobber_ref_p_1 (phi, &ref)) + { + vuse = gimple_vuse (phi); + phi = SSA_NAME_DEF_STMT (vuse); + if (gimple_bb (phi) != phiblock) + return vuse; + if (gimple_code (phi) == GIMPLE_PHI) + { + e = find_edge (block, phiblock); + break; + } + } + else + return NULL_TREE; + + if (e) { - vuse = gimple_vuse (phi); - phi = SSA_NAME_DEF_STMT (vuse); - if (gimple_bb (phi) != phiblock) - return vuse; - if (gimple_code (phi) == GIMPLE_PHI) + if (use_oracle) { - edge e = find_edge (block, phiblock); - return PHI_ARG_DEF (phi, e->dest_idx); + bitmap visited = NULL; + /* Try to find a vuse that dominates this phi node by skipping + non-clobbering statements. */ + vuse = get_continuation_for_phi (phi, &ref, &visited); + if (visited) + BITMAP_FREE (visited); } + else + vuse = NULL_TREE; + if (!vuse) + { + /* If we didn't find any, the value ID can't stay the same, + but return the translated vuse. */ + *same_valid = false; + vuse = PHI_ARG_DEF (phi, e->dest_idx); + } + /* ??? We would like to return vuse here as this is the canonical + upmost vdef that this reference is associated with. But during + insertion of the references into the hash tables we only ever + directly insert with their direct gimple_vuse, hence returning + something else would make us not find the other expression. */ + return PHI_ARG_DEF (phi, e->dest_idx); } return NULL_TREE; @@ -1541,7 +1572,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, tree vuse = ref->vuse; tree newvuse = vuse; VEC (vn_reference_op_s, heap) *newoperands = NULL; - bool changed = false; + bool changed = false, same_valid = true; unsigned int i, j; vn_reference_op_t operand; vn_reference_t newref; @@ -1647,16 +1678,16 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, { newvuse = translate_vuse_through_block (newoperands, ref->set, ref->type, - vuse, phiblock, pred); + vuse, phiblock, pred, + &same_valid); if (newvuse == NULL_TREE) { VEC_free (vn_reference_op_s, heap, newoperands); return NULL; } } - changed |= newvuse != vuse; - if (changed) + if (changed || newvuse != vuse) { unsigned int new_val_id; pre_expr constant; @@ -1690,9 +1721,15 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, } else { - new_val_id = get_next_value_id (); - VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions, - get_max_value_id() + 1); + if (changed || !same_valid) + { + new_val_id = get_next_value_id (); + VEC_safe_grow_cleared (bitmap_set_t, heap, + value_expressions, + get_max_value_id() + 1); + } + else + new_val_id = ref->value_id; newref = vn_reference_insert_pieces (newvuse, ref->set, ref->type, newoperands, @@ -3914,7 +3951,7 @@ compute_avail (void) vn_reference_lookup (gimple_assign_rhs1 (stmt), gimple_vuse (stmt), - false, &ref); + true, &ref); if (!ref) continue; |