aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgbuild.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2017-06-07 08:42:43 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2017-06-07 06:42:43 +0000
commit6fcdf714130596ac05167398c56897d72ab3e759 (patch)
tree48a46acbffe326fefb2dbd7126d7460aa6cd7f1d /gcc/cfgbuild.c
parent96feaf79b2285aca415fda727e51868b95a8e4d9 (diff)
downloadgcc-6fcdf714130596ac05167398c56897d72ab3e759.zip
gcc-6fcdf714130596ac05167398c56897d72ab3e759.tar.gz
gcc-6fcdf714130596ac05167398c56897d72ab3e759.tar.bz2
cfgbuild.c (find_bb_boundaries): Initialize profile of split blocks.
* cfgbuild.c (find_bb_boundaries): Initialize profile of split blocks. (compute_outgoing_frequencies): Also initialize zero counts. (find_many_sub_basic_blocks): Do not produce uninitialized profile around loops; preserve more of profile when nothing changes. From-SVN: r248945
Diffstat (limited to 'gcc/cfgbuild.c')
-rw-r--r--gcc/cfgbuild.c51
1 files changed, 47 insertions, 4 deletions
diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
index a4004f8..f4a4d08 100644
--- a/gcc/cfgbuild.c
+++ b/gcc/cfgbuild.c
@@ -475,6 +475,10 @@ find_bb_boundaries (basic_block bb)
bb = fallthru->dest;
remove_edge (fallthru);
+ /* BB is unreachable at this point - we need to determine its profile
+ once edges are built. */
+ bb->frequency = 0;
+ bb->count = profile_count::uninitialized ();
flow_transfer_insn = NULL;
if (code == CODE_LABEL && LABEL_ALT_ENTRY_P (insn))
make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, 0);
@@ -577,7 +581,7 @@ compute_outgoing_frequencies (basic_block b)
guess_outgoing_edge_probabilities (b);
}
- if (b->count > profile_count::zero ())
+ if (b->count.initialized_p ())
FOR_EACH_EDGE (e, ei, b->succs)
e->count = b->count.apply_probability (e->probability);
}
@@ -590,6 +594,9 @@ void
find_many_sub_basic_blocks (sbitmap blocks)
{
basic_block bb, min, max;
+ bool found = false;
+ auto_vec<unsigned int> n_succs;
+ n_succs.safe_grow_cleared (last_basic_block_for_fn (cfun));
FOR_EACH_BB_FN (bb, cfun)
SET_STATE (bb,
@@ -597,11 +604,24 @@ find_many_sub_basic_blocks (sbitmap blocks)
FOR_EACH_BB_FN (bb, cfun)
if (STATE (bb) == BLOCK_TO_SPLIT)
- find_bb_boundaries (bb);
+ {
+ int n = last_basic_block_for_fn (cfun);
+ unsigned int ns = EDGE_COUNT (bb->succs);
+
+ find_bb_boundaries (bb);
+ if (n == last_basic_block_for_fn (cfun) && ns == EDGE_COUNT (bb->succs))
+ n_succs[bb->index] = EDGE_COUNT (bb->succs);
+ }
FOR_EACH_BB_FN (bb, cfun)
if (STATE (bb) != BLOCK_ORIGINAL)
- break;
+ {
+ found = true;
+ break;
+ }
+
+ if (!found)
+ return;
min = max = bb;
for (; bb != EXIT_BLOCK_PTR_FOR_FN (cfun); bb = bb->next_bb)
@@ -624,14 +644,37 @@ find_many_sub_basic_blocks (sbitmap blocks)
continue;
if (STATE (bb) == BLOCK_NEW)
{
+ bool initialized_src = false, uninitialized_src = false;
bb->count = profile_count::zero ();
bb->frequency = 0;
FOR_EACH_EDGE (e, ei, bb->preds)
{
- bb->count += e->count;
+ if (e->count.initialized_p ())
+ {
+ bb->count += e->count;
+ initialized_src = true;
+ }
+ else
+ uninitialized_src = false;
bb->frequency += EDGE_FREQUENCY (e);
}
+ /* When some edges are missing with read profile, this is
+ most likely because RTL expansion introduced loop.
+ When profile is guessed we may have BB that is reachable
+ from unlikely path as well as from normal path.
+
+ TODO: We should handle loops created during BB expansion
+ correctly here. For now we assume all those loop to cycle
+ precisely once. */
+ if (!initialized_src
+ || (uninitialized_src
+ && profile_status_for_fn (cfun) != PROFILE_READ))
+ bb->count = profile_count::uninitialized ();
}
+ else
+ /* If nothing changed, there is no need to create new BBs. */
+ if (EDGE_COUNT (bb->succs) == n_succs[bb->index])
+ continue;
compute_outgoing_frequencies (bb);
}