143#define DEBUG_TYPE "fix-irreducible"
166char FixIrreducible::ID = 0;
171 "Convert irreducible control-flow into natural loops",
176 "Convert irreducible control-flow into natural loops",
183 auto &CandidateLoops = ParentLoop ? ParentLoop->getSubLoopsVector()
184 : LI.getTopLevelLoopsVector();
188 return NewLoop == L || !NewLoop->contains(L->getHeader());
191 CandidateLoops.
erase(FirstChild, CandidateLoops.end());
193 for (
Loop *Child : ChildLoops) {
194 LLVM_DEBUG(
dbgs() <<
"child loop: " << Child->getHeader()->getName()
198 if (Child->getHeader() == OldHeader) {
199 for (
auto *BB : Child->blocks()) {
200 if (LI.getLoopFor(BB) != Child)
202 LI.changeLoopFor(BB, NewLoop);
206 std::vector<Loop *> GrandChildLoops;
207 std::swap(GrandChildLoops, Child->getSubLoopsVector());
208 for (
auto *GrandChildLoop : GrandChildLoops) {
209 GrandChildLoop->setParentLoop(
nullptr);
210 NewLoop->addChildLoop(GrandChildLoop);
217 Child->setParentLoop(
nullptr);
218 NewLoop->addChildLoop(Child);
230 if (ParentLoop && ParentLoop->
getHeader() == CycleHeader)
246 for (
auto *
G : GuardBlocks) {
247 LLVM_DEBUG(
dbgs() <<
"added guard block to loop: " <<
G->getName() <<
"\n");
248 NewLoop->addBasicBlockToLoop(
G, LI);
251 for (
auto *BB :
C.blocks()) {
252 NewLoop->addBlockEntry(BB);
258 LLVM_DEBUG(
dbgs() <<
"added block from child: " << BB->getName() <<
"\n");
262 << NewLoop->getHeader()->getName() <<
"\n");
267 NewLoop->verifyLoop();
296 assert(
P->getTerminator()->getSuccessor(0) == Header);
302 BasicBlock *Succ0 = Branch->getSuccessor(0) == Header ? Header :
nullptr;
303 BasicBlock *Succ1 = Branch->getSuccessor(1) == Header ? Header :
nullptr;
313 for (
unsigned I = 0;
I < CallBr->getNumSuccessors(); ++
I) {
326 "only supports br and callbr instructions");
331 Predecessors.
clear();
342 Succ0 =
C.contains(Succ0) ? Succ0 :
nullptr;
349 Succ0 =
C.contains(Succ0) ? Succ0 :
nullptr;
351 Succ1 =
C.contains(Succ1) ? Succ1 :
nullptr;
360 for (
unsigned I = 0;
I < CallBr->getNumSuccessors(); ++
I) {
362 if (!
C.contains(Succ))
364 auto It = CallBrTargets.
find(Succ);
366 (It != CallBrTargets.
end()) ? It->second :
nullptr;
371 if (!ExistingTarget) {
373 CallBrTargets[Succ] = NewSucc;
382 "only supports br and callbr instructions");
397 Entries.
insert(
C.entry_rbegin(),
C.entry_rend());
399 CHub.
finalize(&DTU, GuardBlocks,
"irr");
400#if defined(EXPENSIVE_CHECKS)
401 assert(DT.
verify(DominatorTree::VerificationLevel::Full));
403 assert(DT.
verify(DominatorTree::VerificationLevel::Fast));
411 for (
auto *
G : GuardBlocks) {
416 C.setSingleEntry(GuardBlocks[0]);
419 if (
Cycle *Parent =
C.getParentCycle())
420 Parent->verifyCycle();
428 LLVM_DEBUG(
dbgs() <<
"===== Fix irreducible control-flow in function: "
429 <<
F.getName() <<
"\n");
441#if defined(EXPENSIVE_CHECKS)
451bool FixIrreducible::runOnFunction(
Function &
F) {
452 auto *LIWP = getAnalysisIfAvailable<LoopInfoWrapperPass>();
453 LoopInfo *LI = LIWP ? &LIWP->getLoopInfo() :
nullptr;
454 auto &CI = getAnalysis<CycleInfoWrapperPass>().getResult();
455 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
fix Convert irreducible control flow into natural static false void reconnectChildLoops(LoopInfo &LI, Loop *ParentLoop, Loop *NewLoop, BasicBlock *OldHeader)
static void updateLoopInfo(LoopInfo &LI, Cycle &C, ArrayRef< BasicBlock * > GuardBlocks)
static bool FixIrreducibleImpl(Function &F, CycleInfo &CI, DominatorTree &DT, LoopInfo *LI)
static bool fixIrreducible(Cycle &C, CycleInfo &CI, DominatorTree &DT, LoopInfo *LI)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
CallBr instruction, tracking function calls that may not return control but instead transfer it to a ...
Conditional Branch instruction.
Analysis pass which computes a CycleInfo.
Legacy analysis pass which computes a CycleInfo.
iterator find(const_arg_type_t< KeyT > Val)
Analysis pass which computes a DominatorTree.
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
FunctionPass class - This class is used to implement most global optimizations.
void verify() const
Verify that the entire cycle tree well-formed.
void addBlockToCycle(BlockT *Block, CycleT *Cycle)
Assumes that Cycle is the innermost cycle containing Block.
iterator_range< const_toplevel_iterator > toplevel_cycles() const
void print(raw_ostream &Out) const
Print the cycle info.
Analysis pass that exposes the LoopInfo for a function.
void verifyLoop() const
Verify loop structure.
BlockT * getHeader() const
void print(raw_ostream &OS, bool Verbose=false, bool PrintNested=true, unsigned Depth=0) const
Print loop with all the BBs inside it.
void addChildLoop(LoopT *NewChild)
Add the specified loop to be a child of this loop.
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
void addTopLevelLoop(LoopT *New)
This adds the specified loop to the collection of top-level loops.
LoopT * AllocateLoop(ArgsTy &&...Args)
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
void changeLoopFor(const BlockT *BB, LoopT *L)
Change the top-level loop that contains BB to the specified loop.
The legacy pass manager's analysis pass to compute loop information.
Represents a single loop in the control flow graph.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
A vector that has set insertion semantics.
void clear()
Completely clear the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
iterator erase(const_iterator CI)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Unconditional Branch instruction.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI FunctionPass * createFixIrreduciblePass()
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
auto partition(R &&Range, UnaryPredicate P)
Provide wrappers to std::partition which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Printable printBasicBlock(const BasicBlock *BB)
Print BasicBlock BB as an operand or print "<nullptr>" if BB is a nullptr.
auto predecessors(const MachineBasicBlock *BB)
iterator_range< df_iterator< T > > depth_first(const T &G)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI void initializeFixIrreduciblePass(PassRegistry &)
LLVM_ABI BasicBlock * SplitCallBrEdge(BasicBlock *CallBrBlock, BasicBlock *Succ, unsigned SuccIdx, BasicBlock *CallBrTarget=nullptr, DomTreeUpdater *DTU=nullptr, CycleInfo *CI=nullptr, LoopInfo *LI=nullptr, bool *UpdatedLI=nullptr)
Create a new intermediate target block for a callbr edge.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Given a set of branch descriptors [BB, Succ0, Succ1], create a "hub" such that the control flow from ...
void addBranch(BasicBlock *BB, BasicBlock *Succ0, BasicBlock *Succ1=nullptr)
LLVM_ABI std::pair< BasicBlock *, bool > finalize(DomTreeUpdater *DTU, SmallVectorImpl< BasicBlock * > &GuardBlocks, const StringRef Prefix, std::optional< unsigned > MaxControlFlowBooleans=std::nullopt)
Return the unified loop exit block and a flag indicating if the CFG was changed at all.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)