Move the body of the loop in possibly_profitable_path_p that accounts
for one block's stats into its own function. The bail out on an
unthreadable block becomes the m_unprofitable_bb flag. I would've
rather return the unprofitable flag, but once the stats are
accumulated the verdict has to outlive the call and unwind with them,
so it's simpler this way.
gcc/ChangeLog:
* tree-ssa-threadbackward.cc (back_threader_profitability): Add
account_bb and m_unprofitable_bb.
(back_threader_profitability::account_bb): New.
(back_threader_profitability::possibly_profitable_path_p): Use it.
---
gcc/tree-ssa-threadbackward.cc | 86 ++++++++++++++++++++--------------
1 file changed, 51 insertions(+), 35 deletions(-)
diff --git a/gcc/tree-ssa-threadbackward.cc b/gcc/tree-ssa-threadbackward.cc
index a1c476fdfbe..33c00aeb52c 100644
--- a/gcc/tree-ssa-threadbackward.cc
+++ b/gcc/tree-ssa-threadbackward.cc
@@ -66,6 +66,7 @@ public:
bool profitable_path_p (const vec<basic_block> &,
edge taken, bool *irreducible_loop);
private:
+ void account_bb (basic_block, bool);
const bool m_speed_p;
int m_exit_jump_benefit;
bool m_threaded_multiway_branch;
@@ -73,6 +74,7 @@ private:
bool m_threaded_through_latch;
bool m_multiway_branch_in_path;
bool m_contains_hot_bb;
+ bool m_unprofitable_bb;
int m_n_insns;
};
@@ -88,6 +90,50 @@ back_threader_profitability::back_threader_profitability
(bool speed_p,
m_exit_jump_benefit = estimate_num_insns (last, &eni_size_weights);
}
+/* Account for BB in the cumulative stats for the path being threaded.
+ CHECK_MULTIWAY is true for all blocks except the block whose branch
+ we are going to eliminate. */
+
+void
+back_threader_profitability::account_bb (basic_block bb, bool check_multiway)
+{
+ if (!m_contains_hot_bb && m_speed_p)
+ m_contains_hot_bb |= optimize_bb_for_speed_p (bb);
+
+ for (gimple_stmt_iterator gsi = gsi_after_labels (bb);
+ !gsi_end_p (gsi);
+ gsi_next_nondebug (&gsi))
+ {
+ /* Do not allow OpenACC loop markers and __builtin_constant_p on
+ threading paths. The latter is disallowed, because an
+ expression might be constant on two threading paths, and
+ become non-constant (i.e.: phi) when they merge. */
+ gimple *stmt = gsi_stmt (gsi);
+ if (gimple_call_internal_p (stmt, IFN_UNIQUE)
+ || gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P))
+ {
+ m_unprofitable_bb = true;
+ return;
+ }
+ /* Do not count empty statements and labels. */
+ if (gimple_code (stmt) != GIMPLE_NOP
+ && !is_gimple_debug (stmt))
+ m_n_insns += estimate_num_insns (stmt, &eni_size_weights);
+ }
+
+ /* We do not look at the block with the threaded branch in this loop.
+ So if any block with a last statement that is a GIMPLE_SWITCH or
+ GIMPLE_GOTO is seen, then we have a multiway branch on our path. */
+ if (check_multiway)
+ {
+ gimple *last = *gsi_last_bb (bb);
+ if (last
+ && (gimple_code (last) == GIMPLE_SWITCH
+ || gimple_code (last) == GIMPLE_GOTO))
+ m_multiway_branch_in_path = true;
+ }
+}
+
// Back threader flags.
#define BT_NONE 0
// Generate fast code at the expense of code size.
@@ -635,7 +681,6 @@ back_threader_profitability::possibly_profitable_path_p
if (m_path.length () <= 1)
return false;
- gimple_stmt_iterator gsi;
loop_p loop = m_path[0]->loop_father;
// We recompute the following, when we rewrite possibly_profitable_path_p
@@ -644,6 +689,7 @@ back_threader_profitability::possibly_profitable_path_p
m_threaded_through_latch = false;
m_multiway_branch_in_path = false;
m_contains_hot_bb = false;
+ m_unprofitable_bb = false;
/* Count the number of instructions on the path: as these instructions
will have to be duplicated, we will not record the path if there
@@ -661,41 +707,11 @@ back_threader_profitability::possibly_profitable_path_p
it ends in a multiway branch. */
if (j < m_path.length () - 1)
{
- if (!m_contains_hot_bb && m_speed_p)
- m_contains_hot_bb |= optimize_bb_for_speed_p (bb);
- for (gsi = gsi_after_labels (bb);
- !gsi_end_p (gsi);
- gsi_next_nondebug (&gsi))
- {
- /* Do not allow OpenACC loop markers and __builtin_constant_p on
- threading paths. The latter is disallowed, because an
- expression might be constant on two threading paths, and
- become non-constant (i.e.: phi) when they merge. */
- gimple *stmt = gsi_stmt (gsi);
- if (gimple_call_internal_p (stmt, IFN_UNIQUE)
- || gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P))
- return false;
- /* Do not count empty statements and labels. */
- if (gimple_code (stmt) != GIMPLE_NOP
- && !is_gimple_debug (stmt))
- m_n_insns += estimate_num_insns (stmt, &eni_size_weights);
- }
-
- /* We do not look at the block with the threaded branch
- in this loop. So if any block with a last statement that
- is a GIMPLE_SWITCH or GIMPLE_GOTO is seen, then we have a
- multiway branch on our path.
-
- The block in PATH[0] is special, it's the block were we're
+ /* The block in PATH[0] is special, it's the block were we're
going to be able to eliminate its branch. */
- if (j > 0)
- {
- gimple *last = *gsi_last_bb (bb);
- if (last
- && (gimple_code (last) == GIMPLE_SWITCH
- || gimple_code (last) == GIMPLE_GOTO))
- m_multiway_branch_in_path = true;
- }
+ account_bb (bb, /*check_multiway=*/j > 0);
+ if (m_unprofitable_bb)
+ return false;
}
/* Note if we thread through the latch, we will want to include
--
2.53.0