aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-ssa-split-paths.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2017-02-24 08:04:31 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2017-02-24 08:04:31 +0000
commit7699e88f68de2f5488ad260fdd35ee3a2b910014 (patch)
tree879d6e9c772604641f126febfe83c337e3d996fd /gcc/gimple-ssa-split-paths.c
parentf83002c7baab042876e9a460e93dd528844b1eb5 (diff)
downloadgcc-7699e88f68de2f5488ad260fdd35ee3a2b910014.zip
gcc-7699e88f68de2f5488ad260fdd35ee3a2b910014.tar.gz
gcc-7699e88f68de2f5488ad260fdd35ee3a2b910014.tar.bz2
re PR tree-optimization/79389 (30% performance regression in SciMark2 MonteCarlo)
2017-02-24 Richard Biener <rguenther@suse.de> PR tree-optimization/79389 * gimple-ssa-split-paths.c (is_feasible_trace): Verify more properly that a threading opportunity exists. Detect conditional copy/constant propagation opportunities. * gcc.dg/tree-ssa/split-path-10.c: New testcase. From-SVN: r245696
Diffstat (limited to 'gcc/gimple-ssa-split-paths.c')
-rw-r--r--gcc/gimple-ssa-split-paths.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/gcc/gimple-ssa-split-paths.c b/gcc/gimple-ssa-split-paths.c
index f1bf7ec..0f6b241 100644
--- a/gcc/gimple-ssa-split-paths.c
+++ b/gcc/gimple-ssa-split-paths.c
@@ -232,12 +232,32 @@ is_feasible_trace (basic_block bb)
/* But for memory the PHI alone isn't good enough. */
&& ! virtual_operand_p (gimple_phi_result (stmt)))
{
+ bool found_unchanged_path = false;
for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
if (gimple_phi_arg_def (phi, i) == gimple_phi_result (stmt))
{
- found_useful_phi = true;
+ found_unchanged_path = true;
break;
}
+ /* If we found an unchanged path this can only be a threading
+ opportunity if we have uses of the loop header PHI result
+ in a stmt dominating the merge block. Otherwise the
+ splitting may prevent if-conversion. */
+ if (found_unchanged_path)
+ {
+ use_operand_p use2_p;
+ imm_use_iterator iter2;
+ FOR_EACH_IMM_USE_FAST (use2_p, iter2, gimple_phi_result (stmt))
+ {
+ basic_block use_bb = gimple_bb (USE_STMT (use2_p));
+ if (use_bb != bb
+ && dominated_by_p (CDI_DOMINATORS, bb, use_bb))
+ {
+ found_useful_phi = true;
+ break;
+ }
+ }
+ }
if (found_useful_phi)
break;
}
@@ -245,7 +265,32 @@ is_feasible_trace (basic_block bb)
if (found_useful_phi)
break;
}
- if (! found_useful_phi)
+ /* There is one exception namely a controlling condition we can propagate
+ an equivalence from to the joiner. */
+ bool found_cprop_opportunity = false;
+ basic_block dom = get_immediate_dominator (CDI_DOMINATORS, bb);
+ gcond *cond = as_a <gcond *> (last_stmt (dom));
+ if (gimple_cond_code (cond) == EQ_EXPR
+ || gimple_cond_code (cond) == NE_EXPR)
+ for (unsigned i = 0; i < 2; ++i)
+ {
+ tree op = gimple_op (cond, i);
+ if (TREE_CODE (op) == SSA_NAME)
+ {
+ use_operand_p use_p;
+ imm_use_iterator iter;
+ FOR_EACH_IMM_USE_FAST (use_p, iter, op)
+ if (gimple_bb (USE_STMT (use_p)) == bb)
+ {
+ found_cprop_opportunity = true;
+ break;
+ }
+ }
+ if (found_cprop_opportunity)
+ break;
+ }
+
+ if (! found_useful_phi && ! found_cprop_opportunity)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,