aboutsummaryrefslogtreecommitdiff
path: root/gcc/predict.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2012-02-10 12:21:16 +0000
committerJan Hubicka <jh@suse.cz>2012-02-10 12:21:16 +0000
commitb1974ad8cd4105734ec0e3b5567a09f7dbb8e798 (patch)
tree5b6fdd5a22647ed052e64b528c984e777237ece1 /gcc/predict.c
parent2dfe2df5d281c3c69b8006709266c773f875196d (diff)
PR middle-end/48600
* predict.c (predict_paths_for_bb): Prevent looping. (predict_paths_leading_to_edge, predict_paths_leading_to): Update. * g++.dg/torture/pr48600.C: New testcase. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@184089 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/predict.c')
-rw-r--r--gcc/predict.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/gcc/predict.c b/gcc/predict.c
index 92365317905..67131c9e759 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -1827,7 +1827,8 @@ tree_estimate_probability_driver (void)
static void
predict_paths_for_bb (basic_block cur, basic_block bb,
enum br_predictor pred,
- enum prediction taken)
+ enum prediction taken,
+ bitmap visited)
{
edge e;
edge_iterator ei;
@@ -1848,7 +1849,7 @@ predict_paths_for_bb (basic_block cur, basic_block bb,
continue;
gcc_assert (bb == cur || dominated_by_p (CDI_POST_DOMINATORS, cur, bb));
- /* See if there is how many edge from e->src that is not abnormal
+ /* See if there is an 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
@@ -1861,16 +1862,20 @@ predict_paths_for_bb (basic_block cur, basic_block bb,
/* If there is non-abnormal path leaving e->src, predict edge
using predictor. Otherwise we need to look for paths
- leading to e->src. */
+ leading to e->src.
+
+ The second may lead to infinite loop in the case we are predicitng
+ regions that are only reachable by abnormal edges. We simply
+ prevent visiting given BB twice. */
if (found)
predict_edge_def (e, pred, taken);
- else
- predict_paths_for_bb (e->src, e->src, pred, taken);
+ else if (!bitmap_set_bit (visited, e->src->index))
+ predict_paths_for_bb (e->src, e->src, pred, taken, visited);
}
for (son = first_dom_son (CDI_POST_DOMINATORS, cur);
son;
son = next_dom_son (CDI_POST_DOMINATORS, son))
- predict_paths_for_bb (son, bb, pred, taken);
+ predict_paths_for_bb (son, bb, pred, taken, visited);
}
/* Sets branch probabilities according to PREDiction and
@@ -1880,7 +1885,9 @@ static void
predict_paths_leading_to (basic_block bb, enum br_predictor pred,
enum prediction taken)
{
- predict_paths_for_bb (bb, bb, pred, taken);
+ bitmap visited = BITMAP_ALLOC (NULL);
+ predict_paths_for_bb (bb, bb, pred, taken, visited);
+ BITMAP_FREE (visited);
}
/* Like predict_paths_leading_to but take edge instead of basic block. */
@@ -1903,7 +1910,11 @@ predict_paths_leading_to_edge (edge e, enum br_predictor pred,
break;
}
if (!has_nonloop_edge)
- predict_paths_for_bb (bb, bb, pred, taken);
+ {
+ bitmap visited = BITMAP_ALLOC (NULL);
+ predict_paths_for_bb (bb, bb, pred, taken, visited);
+ BITMAP_FREE (visited);
+ }
else
predict_edge_def (e, pred, taken);
}