Abstract out can_duplicate_block_on_edge_p from tree-ssa-threadedge.cc [PR126896] Both the jump threader's joiner registration and the upcoming phiopt replication of PHI-of-compares joins need a way to determine if a block on an edge can be duplicated. Abstract out the code in tree-ssa-threadedge.cc to be reusable by the upcoming work. PR tree-optimization/126896 gcc/ChangeLog: * cfghooks.cc (can_duplicate_block_on_edge_p): New. * cfghooks.h (can_duplicate_block_on_edge_p): Declare. * tree-ssa-threadedge.cc: Include cfghooks.h. (jump_threader::thread_across_edge): Use can_duplicate_block_on_edge_p.
diff --git a/gcc/cfghooks.cc b/gcc/cfghooks.cc index a219b4a..9e20c82 100644 --- a/gcc/cfghooks.cc +++ b/gcc/cfghooks.cc
@@ -1141,6 +1141,29 @@ return cfg_hooks->can_duplicate_block_p (bb); } +/* Returns true if we can duplicate E's destination with E redirected to the + copy. */ + +bool +can_duplicate_block_on_edge_p (edge e) +{ + basic_block bb = e->dest; + + if (!can_duplicate_block_p (bb)) + return false; + + if (e->flags & EDGE_COMPLEX) + return false; + + edge s; + edge_iterator ei; + FOR_EACH_EDGE (s, ei, bb->succs) + if (s->flags & EDGE_COMPLEX) + return false; + + return true; +} + /* Duplicate basic block BB, place it after AFTER (if non-null) and redirect edge E to it (if non-null). Return the new basic block.
diff --git a/gcc/cfghooks.h b/gcc/cfghooks.h index aa7071e..8d7cb2d 100644 --- a/gcc/cfghooks.h +++ b/gcc/cfghooks.h
@@ -252,6 +252,7 @@ extern void predict_edge (edge e, enum br_predictor predictor, int probability); extern bool predicted_by_p (const_basic_block bb, enum br_predictor predictor); extern bool can_duplicate_block_p (const_basic_block); +extern bool can_duplicate_block_on_edge_p (edge); extern basic_block duplicate_block (basic_block, edge, basic_block, copy_bb_data * = NULL); extern bool block_ends_with_call_p (basic_block bb);
diff --git a/gcc/tree-ssa-threadedge.cc b/gcc/tree-ssa-threadedge.cc index ce757b4..98184d1 100644 --- a/gcc/tree-ssa-threadedge.cc +++ b/gcc/tree-ssa-threadedge.cc
@@ -22,6 +22,7 @@ #include "system.h" #include "coretypes.h" #include "backend.h" +#include "cfghooks.h" #include "tree.h" #include "gimple.h" #include "predict.h" @@ -1010,12 +1011,11 @@ /* If E->dest has abnormal outgoing edges, then there's no guarantee we can safely redirect any of the edges. Just punt those cases. */ - FOR_EACH_EDGE (taken_edge, ei, e->dest->succs) - if (taken_edge->flags & EDGE_COMPLEX) - { - m_state->pop (); - return; - } + if (!can_duplicate_block_on_edge_p (e)) + { + m_state->pop (); + return; + } /* Look at each successor of E->dest to see if we can thread through it. */ FOR_EACH_EDGE (taken_edge, ei, e->dest->succs)