diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2017-07-03 14:42:07 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2017-07-03 12:42:07 +0000 |
commit | b5db8b44e55b6d95865c59e92779dc7dc2e3c273 (patch) | |
tree | a28dda296bdd6460ef9fc637fbd48af72ecf5a5d | |
parent | edfe99a43c4c1b96132511c45c1cc0e627c4e1be (diff) | |
download | gcc-b5db8b44e55b6d95865c59e92779dc7dc2e3c273.zip gcc-b5db8b44e55b6d95865c59e92779dc7dc2e3c273.tar.gz gcc-b5db8b44e55b6d95865c59e92779dc7dc2e3c273.tar.bz2 |
tree-cfgcleanup.c (want_merge_blocks_p): New function.
* tree-cfgcleanup.c (want_merge_blocks_p): New function.
(cleanup_tree_cfg_bb): Use it.
* profile-count.h (profile_count::of_for_merging, profile_count::merge):
New functions.
* tree-cfg.c (gimple_merge_blocks): Use profile_count::merge.
From-SVN: r249907
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/profile-count.h | 25 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 2 | ||||
-rw-r--r-- | gcc/tree-cfgcleanup.c | 17 |
4 files changed, 49 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 19c6c29..3d0826a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2017-07-02 Jan Hubicka <hubicka@ucw.cz> + * tree-cfgcleanup.c (want_merge_blocks_p): New function. + (cleanup_tree_cfg_bb): Use it. + * profile-count.h (profile_count::of_for_merging, profile_count::merge): + New functions. + * tree-cfg.c (gimple_merge_blocks): Use profile_count::merge. + +2017-07-02 Jan Hubicka <hubicka@ucw.cz> + PR bootstrap/81285 * loop-doloop.c (add_test): Update profile. diff --git a/gcc/profile-count.h b/gcc/profile-count.h index 73bc8ed..e63b964 100644 --- a/gcc/profile-count.h +++ b/gcc/profile-count.h @@ -565,6 +565,31 @@ public: return initialized_p (); } + /* When merging basic blocks, the two different profile counts are unified. + Return true if this can be done without losing info about profile. + The only case we care about here is when first BB contains something + that makes it terminate in a way not visible in CFG. */ + bool ok_for_merging (profile_count other) const + { + if (m_quality < profile_adjusted + || other.m_quality < profile_adjusted) + return true; + return !(other < *this); + } + + /* When merging two BBs with different counts, pick common count that looks + most representative. */ + profile_count merge (profile_count other) const + { + if (*this == other || !other.initialized_p () + || m_quality > other.m_quality) + return *this; + if (other.m_quality > m_quality + || other > *this) + return other; + return *this; + } + /* Basic operations. */ bool operator== (const profile_count &other) const { diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 6add040..e0cee12 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -2076,7 +2076,7 @@ gimple_merge_blocks (basic_block a, basic_block b) profiles. */ if (a->loop_father == b->loop_father) { - a->count = MAX (a->count, b->count); + a->count = a->count.merge (b->count); a->frequency = MAX (a->frequency, b->frequency); } diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index b4127f9..c6e5c8d 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -636,6 +636,19 @@ fixup_noreturn_call (gimple *stmt) return changed; } +/* Return true if we want to merge BB1 and BB2 into a single block. */ + +static bool +want_merge_blocks_p (basic_block bb1, basic_block bb2) +{ + if (!can_merge_blocks_p (bb1, bb2)) + return false; + gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb1); + if (gsi_end_p (gsi) || !stmt_can_terminate_bb_p (gsi_stmt (gsi))) + return true; + return bb1->count.ok_for_merging (bb2->count); +} + /* Tries to cleanup cfg in basic block BB. Returns true if anything changes. */ @@ -652,7 +665,7 @@ cleanup_tree_cfg_bb (basic_block bb) This happens when we visit BBs in a non-optimal order and avoids quadratic behavior with adjusting stmts BB pointer. */ if (single_pred_p (bb) - && can_merge_blocks_p (single_pred (bb), bb)) + && want_merge_blocks_p (single_pred (bb), bb)) /* But make sure we _do_ visit it. When we remove unreachable paths ending in a backedge we fail to mark the destinations predecessors as changed. */ @@ -662,7 +675,7 @@ cleanup_tree_cfg_bb (basic_block bb) conditional branches (due to the elimination of single-valued PHI nodes). */ else if (single_succ_p (bb) - && can_merge_blocks_p (bb, single_succ (bb))) + && want_merge_blocks_p (bb, single_succ (bb))) { merge_blocks (bb, single_succ (bb)); return true; |