Commit b5db8b44 by Jan Hubicka Committed by Jan Hubicka

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
parent edfe99a4
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.
......
......@@ -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
{
......
......@@ -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);
}
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment