aboutsummaryrefslogtreecommitdiff
path: root/gcc/predict.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2010-07-02 09:39:54 +0000
committerJan Hubicka <jh@suse.cz>2010-07-02 09:39:54 +0000
commit8a14a4cb6fec7c4e86c0141161d2c47ea0b7bddc (patch)
tree46403e3bed83c82abaaf936bc88c4c21b1cd0aa1 /gcc/predict.c
parentaa8b3e2d22df9400c94255ec63630fc5e558eabb (diff)
PR middle-end/44706
* predict.c (predict_paths_for_bb): Handle case when control dependence BB has only abnormal edges. * g++.dg/tree-ssa/pr44706.C: New testcase. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@161691 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/predict.c')
-rw-r--r--gcc/predict.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/gcc/predict.c b/gcc/predict.c
index 5d61140e4e6..15d573b50a2 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -1786,8 +1786,33 @@ predict_paths_for_bb (basic_block cur, basic_block bb,
if (e->src->index >= NUM_FIXED_BLOCKS
&& !dominated_by_p (CDI_POST_DOMINATORS, e->src, bb))
{
+ edge e2;
+ edge_iterator ei2;
+ bool found = false;
+
+ /* Ignore abnormals, we predict them as not taken anyway. */
+ if (e->flags & (EDGE_EH | EDGE_FAKE | EDGE_ABNORMAL))
+ continue;
gcc_assert (bb == cur || dominated_by_p (CDI_POST_DOMINATORS, cur, bb));
- predict_edge_def (e, pred, taken);
+
+ /* See if there is how many edge from e->src that is not abnormal
+ and does not lead to BB. */
+ FOR_EACH_EDGE (e2, ei2, e->src->succs)
+ if (e2 != e
+ && !(e2->flags & (EDGE_EH | EDGE_FAKE | EDGE_ABNORMAL))
+ && !dominated_by_p (CDI_POST_DOMINATORS, e2->dest, bb))
+ {
+ found = true;
+ break;
+ }
+
+ /* If there is non-abnormal path leaving e->src, predict edge
+ using predictor. Otherwise we need to look for paths
+ leading to e->src. */
+ if (found)
+ predict_edge_def (e, pred, taken);
+ else
+ predict_paths_for_bb (e->src, e->src, pred, taken);
}
for (son = first_dom_son (CDI_POST_DOMINATORS, cur);
son;