diff options
author | Richard Biener <rguenther@suse.de> | 2017-02-24 08:04:31 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2017-02-24 08:04:31 +0000 |
commit | 7699e88f68de2f5488ad260fdd35ee3a2b910014 (patch) | |
tree | 879d6e9c772604641f126febfe83c337e3d996fd /gcc/gimple-ssa-split-paths.c | |
parent | f83002c7baab042876e9a460e93dd528844b1eb5 (diff) | |
download | gcc-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.c | 49 |
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, |