This moves the optimize_unreachable to forwprop from fab.
There is a slightly optimization here in that the first
statement is checked and outside of the main fold loop. And if
the statement is __builtin_unreachable, then call optimize_unreachable.
Bootstrapped and tested on x86_64-linux-gnu.
PR tree-optimization/121762
gcc/ChangeLog:
* tree-ssa-ccp.cc (optimize_unreachable): Move to tree-ssa-forwprop.cc
(pass_fold_builtins::execute): Remove handling of __builtin_unreachable.
* tree-ssa-forwprop.cc (optimize_unreachable): New function from
tree-ssa-ccp.cc. Change argument to bb. Remove check on first statement
being the __builtin_unreachable since it is handled already.
(pass_forwprop::execute): Handle first statement as being
__builtin_unreachable
by calling optimize_unreachable.
Signed-off-by: Andrew Pinski <[email protected]>
---
gcc/tree-ssa-ccp.cc | 58 -------------------------------------
gcc/tree-ssa-forwprop.cc | 62 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 62 insertions(+), 58 deletions(-)
diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc
index 739d3be9129..b69a8b64a61 100644
--- a/gcc/tree-ssa-ccp.cc
+++ b/gcc/tree-ssa-ccp.cc
@@ -3202,58 +3202,6 @@ optimize_stdarg_builtin (gimple_stmt_iterator *gsi,
gimple *call)
}
}
-/* Attemp to make the block of __builtin_unreachable I unreachable by changing
- the incoming jumps. Return true if at least one jump was changed. */
-
-static bool
-optimize_unreachable (gimple_stmt_iterator i)
-{
- basic_block bb = gsi_bb (i);
- gimple_stmt_iterator gsi;
- gimple *stmt;
- edge_iterator ei;
- edge e;
- bool ret;
-
- if (flag_sanitize & SANITIZE_UNREACHABLE)
- return false;
- gsi = gsi_start_nondebug_after_labels_bb (bb);
- /* Only handle the case that __builtin_unreachable is the first
- statement in the block. We rely on DCE to remove stmts
- without side-effects before __builtin_unreachable. */
- if (*gsi != *i)
- return false;
-
- ret = false;
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- gsi = gsi_last_bb (e->src);
- if (gsi_end_p (gsi))
- continue;
-
- stmt = gsi_stmt (gsi);
- if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
- {
- if (e->flags & EDGE_TRUE_VALUE)
- gimple_cond_make_false (cond_stmt);
- else if (e->flags & EDGE_FALSE_VALUE)
- gimple_cond_make_true (cond_stmt);
- else
- gcc_unreachable ();
- update_stmt (cond_stmt);
- }
- else
- {
- /* Todo: handle other cases. Note that unreachable switch case
- statements have already been removed. */
- continue;
- }
-
- ret = true;
- }
-
- return ret;
-}
/* Convert
_1 = __atomic_fetch_or_* (ptr_6, 1, _3);
@@ -4235,12 +4183,6 @@ pass_fold_builtins::execute (function *fun)
tree result = NULL_TREE;
switch (DECL_FUNCTION_CODE (callee))
{
-
- case BUILT_IN_UNREACHABLE:
- if (optimize_unreachable (i))
- cfg_changed = true;
- break;
-
case BUILT_IN_ATOMIC_ADD_FETCH_1:
case BUILT_IN_ATOMIC_ADD_FETCH_2:
case BUILT_IN_ATOMIC_ADD_FETCH_4:
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index 06ce34c6782..c7ac96a28aa 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -4903,6 +4903,49 @@ public:
bool m_full_walk = false;
}; // class pass_forwprop
+/* Attemp to make the BB block of __builtin_unreachable unreachable by changing
+ the incoming jumps. Return true if at least one jump was changed. */
+
+static bool
+optimize_unreachable (basic_block bb)
+{
+ gimple_stmt_iterator gsi;
+ gimple *stmt;
+ edge_iterator ei;
+ edge e;
+ bool ret;
+
+ ret = false;
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ {
+ gsi = gsi_last_bb (e->src);
+ if (gsi_end_p (gsi))
+ continue;
+
+ stmt = gsi_stmt (gsi);
+ if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
+ {
+ if (e->flags & EDGE_TRUE_VALUE)
+ gimple_cond_make_false (cond_stmt);
+ else if (e->flags & EDGE_FALSE_VALUE)
+ gimple_cond_make_true (cond_stmt);
+ else
+ gcc_unreachable ();
+ update_stmt (cond_stmt);
+ }
+ else
+ {
+ /* Todo: handle other cases. Note that unreachable switch case
+ statements have already been removed. */
+ continue;
+ }
+
+ ret = true;
+ }
+
+ return ret;
+}
+
unsigned int
pass_forwprop::execute (function *fun)
{
@@ -4949,6 +4992,25 @@ pass_forwprop::execute (function *fun)
edge_iterator ei;
edge e;
+ if (last_p
+ && !(flag_sanitize & SANITIZE_UNREACHABLE))
+ {
+ gimple_stmt_iterator gsi;
+ gsi = gsi_start_nondebug_after_labels_bb (bb);
+ if (!gsi_end_p (gsi))
+ if (gcall *call = dyn_cast<gcall*>(*gsi))
+ {
+ tree callee = gimple_call_fndecl (call);
+ if (callee
+ && fndecl_built_in_p (callee, BUILT_IN_UNREACHABLE)
+ && optimize_unreachable (bb))
+ {
+ cfg_changed = true;
+ continue;
+ }
+ }
+ }
+
/* Skip processing not executable blocks. We could improve
single_use tracking by at least unlinking uses from unreachable
blocks but since blocks with uses are not processed in a
--
2.43.0