aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2017-07-03 14:42:07 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2017-07-03 12:42:07 +0000
commitb5db8b44e55b6d95865c59e92779dc7dc2e3c273 (patch)
treea28dda296bdd6460ef9fc637fbd48af72ecf5a5d
parentedfe99a43c4c1b96132511c45c1cc0e627c4e1be (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/profile-count.h25
-rw-r--r--gcc/tree-cfg.c2
-rw-r--r--gcc/tree-cfgcleanup.c17
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;