37#define DEBUG_TYPE "break-crit-edges"
49 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
50 auto *DT = DTWP ? &DTWP->getDomTree() :
nullptr;
52 auto *PDTWP = getAnalysisIfAvailable<PostDominatorTreeWrapperPass>();
53 auto *PDT = PDTWP ? &PDTWP->getPostDomTree() :
nullptr;
55 auto *LIWP = getAnalysisIfAvailable<LoopInfoWrapperPass>();
56 auto *LI = LIWP ? &LIWP->getLoopInfo() :
nullptr;
73char BreakCriticalEdges::ID = 0;
75 "Break critical edges in CFG",
false,
false)
80 return new BreakCriticalEdges();
103 const Twine &BBName) {
113 const Twine &BBName) {
114 assert(!isa<IndirectBrInst>(TI) &&
115 "Cannot split critical edge from IndirectBrInst");
122 if (DestBB->
isEHPad())
return nullptr;
124 if (
Options.IgnoreUnreachableDests &&
134 if (
Loop *TIL = LI->getLoopFor(TIBB)) {
148 if (LI->getLoopFor(
P) != TIL) {
160 if (
Options.PreserveLoopSimplify)
169 if (BBName.
str() !=
"")
182 F.insert(++FBBI, NewBB);
211 if (
Options.MergeIdenticalEdges) {
228 MSSAU->wireOldPredecessorsToNewImmediatePredecessor(
229 DestBB, NewBB, {TIBB},
Options.MergeIdenticalEdges);
231 if (!DT && !PDT && !LI)
251 DT->applyUpdates(Updates);
253 PDT->applyUpdates(Updates);
258 if (
Loop *TIL = LI->getLoopFor(TIBB)) {
261 if (
Loop *DestLoop = LI->getLoopFor(DestBB)) {
262 if (TIL == DestLoop) {
264 DestLoop->addBasicBlockToLoop(NewBB, *LI);
265 }
else if (TIL->contains(DestLoop)) {
267 TIL->addBasicBlockToLoop(NewBB, *LI);
268 }
else if (DestLoop->contains(TIL)) {
270 DestLoop->addBasicBlockToLoop(NewBB, *LI);
276 assert(DestLoop->getHeader() == DestBB &&
277 "Should not create irreducible loops!");
278 if (
Loop *
P = DestLoop->getParentLoop())
279 P->addBasicBlockToLoop(NewBB, *LI);
285 if (!TIL->contains(DestBB)) {
286 assert(!TIL->contains(NewBB) &&
287 "Split point for loop exit is contained in loop!");
294 if (!LoopPreds.
empty()) {
295 assert(!DestBB->
isEHPad() &&
"We don't split edges to EH pads!");
297 DestBB, LoopPreds,
"split", DT, LI, MSSAU,
Options.PreserveLCSSA);
321 case Instruction::IndirectBr:
326 case Instruction::Br:
327 case Instruction::Switch:
339 bool IgnoreBlocksWithoutPHI,
347 if (isa<IndirectBrInst>(BB.getTerminator()))
355 bool ShouldUpdateAnalysis = BPI && BFI;
356 bool Changed =
false;
358 if (IgnoreBlocksWithoutPHI &&
Target->phis().empty())
365 if (!IBRPred || OtherPreds.
empty())
375 if (ShouldUpdateAnalysis) {
376 EdgeProbabilities.
reserve(
Target->getTerminator()->getNumSuccessors());
377 for (
unsigned I = 0, E =
Target->getTerminator()->getNumSuccessors();
384 if (ShouldUpdateAnalysis) {
387 BFI->setBlockFreq(BodyBlock, BFI->getBlockFreq(
Target));
405 Src->getTerminator()->replaceUsesOfWith(
Target, DirectSucc);
406 if (ShouldUpdateAnalysis)
407 BlockFreqForDirectSucc += BFI->getBlockFreq(Src) *
410 if (ShouldUpdateAnalysis) {
411 BFI->setBlockFreq(DirectSucc, BlockFreqForDirectSucc);
413 BFI->getBlockFreq(
Target) - BlockFreqForDirectSucc;
414 BFI->setBlockFreq(
Target, NewBlockFreqForTarget);
428 "Block was expected to only contain PHIs");
430 while (Indirect !=
End) {
431 PHINode *DirPHI = cast<PHINode>(Direct);
432 PHINode *IndPHI = cast<PHINode>(Indirect);
static BasicBlock * findIBRPredecessor(BasicBlock *BB, SmallVectorImpl< BasicBlock * > &OtherPreds)
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
static cl::opt< bool > SplitAllCriticalEdges("phi-elim-split-all-critical-edges", cl::init(false), cl::Hidden, cl::desc("Split all critical edges during " "PHI elimination"))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
A container for analyses that lazily runs them and caches their results.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addPreservedID(const void *ID)
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const Instruction * getFirstNonPHIOrDbgOrLifetime(bool SkipPseudoOp=true) const
Returns a pointer to the first instruction in this block that is not a PHINode, a debug intrinsic,...
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
bool isEHPad() const
Return true if this basic block is an exception handling block.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs=false)
Update PHI nodes in this BasicBlock before removal of predecessor Pred.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Conditional or Unconditional Branch instruction.
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
Analysis providing branch probability information.
void eraseBlock(const BasicBlock *BB)
Forget analysis results for the given basic block.
void setEdgeProbability(const BasicBlock *Src, const SmallVectorImpl< BranchProbability > &Probs)
Set the raw probabilities for all edges from the given block.
BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
Analysis pass which computes a DominatorTree.
static constexpr UpdateKind Delete
static constexpr UpdateKind Insert
Legacy analysis pass which computes a DominatorTree.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
BasicBlockListType::iterator iterator
unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
void setSuccessor(unsigned Idx, BasicBlock *BB)
Update the specified successor to point at the provided block.
Analysis pass that exposes the LoopInfo for a function.
The legacy pass manager's analysis pass to compute loop information.
Represents a single loop in the control flow graph.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
void setIncomingBlock(unsigned i, BasicBlock *BB)
Value * removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty=true)
Remove an incoming value.
Value * getIncomingValueForBlock(const BasicBlock *BB) const
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserve()
Mark an analysis as preserved.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
A SetVector that performs no allocations if smaller than a certain size.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
std::string str() const
Return the twine contents as a std::string.
Type * getType() const
All values are typed, get the type of this value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
StringRef getName() const
Return a constant reference to the value's name.
const ParentTy * getParent() const
self_iterator getIterator()
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
auto successors(const MachineBasicBlock *BB)
BasicBlock * SplitKnownCriticalEdge(Instruction *TI, unsigned SuccNum, const CriticalEdgeSplittingOptions &Options=CriticalEdgeSplittingOptions(), const Twine &BBName="")
If it is known that an edge is critical, SplitKnownCriticalEdge can be called directly,...
bool SplitIndirectBrCriticalEdges(Function &F, bool IgnoreBlocksWithoutPHI, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr, DebugInfoFinder *DIFinder=nullptr)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
void initializeBreakCriticalEdgesPass(PassRegistry &)
BasicBlock * SplitBlockPredecessors(BasicBlock *BB, ArrayRef< BasicBlock * > Preds, const char *Suffix, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool PreserveLCSSA=false)
This method introduces at least one new basic block into the function and moves some of the predecess...
void createPHIsForSplitLoopExit(ArrayRef< BasicBlock * > Preds, BasicBlock *SplitBB, BasicBlock *DestBB)
When a loop exit edge is split, LCSSA form may require new PHIs in the new exit block.
BasicBlock * SplitCriticalEdge(Instruction *TI, unsigned SuccNum, const CriticalEdgeSplittingOptions &Options=CriticalEdgeSplittingOptions(), const Twine &BBName="")
If this edge is a critical edge, insert a new node to split the critical edge.
bool isCriticalEdge(const Instruction *TI, unsigned SuccNum, bool AllowIdenticalEdges=false)
Return true if the specified edge is a critical edge.
char & BreakCriticalEdgesID
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
FunctionPass * createBreakCriticalEdgesPass()
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Option class for critical edge splitting.