diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp | 293 |
1 files changed, 90 insertions, 203 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/contrib/llvm-project/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp index 633d077e6492..7eb0ba1c2c17 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -24,7 +24,6 @@ #include "llvm/Analysis/LoopAnalysisManager.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopIterator.h" -#include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/MemorySSA.h" #include "llvm/Analysis/MemorySSAUpdater.h" #include "llvm/Analysis/MustExecute.h" @@ -46,8 +45,6 @@ #include "llvm/IR/ProfDataUtils.h" #include "llvm/IR/Use.h" #include "llvm/IR/Value.h" -#include "llvm/InitializePasses.h" -#include "llvm/Pass.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -368,10 +365,11 @@ static void rewritePHINodesForExitAndUnswitchedBlocks(BasicBlock &ExitBB, bool FullUnswitch) { assert(&ExitBB != &UnswitchedBB && "Must have different loop exit and unswitched blocks!"); - Instruction *InsertPt = &*UnswitchedBB.begin(); + BasicBlock::iterator InsertPt = UnswitchedBB.begin(); for (PHINode &PN : ExitBB.phis()) { auto *NewPN = PHINode::Create(PN.getType(), /*NumReservedValues*/ 2, - PN.getName() + ".split", InsertPt); + PN.getName() + ".split"); + NewPN->insertBefore(InsertPt); // Walk backwards over the old PHI node's inputs to minimize the cost of // removing each one. We have to do this weird loop manually so that we @@ -609,7 +607,7 @@ static bool unswitchTrivialBranch(Loop &L, BranchInst &BI, DominatorTree &DT, UnswitchedBB = LoopExitBB; } else { UnswitchedBB = - SplitBlock(LoopExitBB, &LoopExitBB->front(), &DT, &LI, MSSAU); + SplitBlock(LoopExitBB, LoopExitBB->begin(), &DT, &LI, MSSAU, "", false); } if (MSSAU && VerifyMemorySSA) @@ -623,7 +621,7 @@ static bool unswitchTrivialBranch(Loop &L, BranchInst &BI, DominatorTree &DT, // If fully unswitching, we can use the existing branch instruction. // Splice it into the old PH to gate reaching the new preheader and re-point // its successors. - OldPH->splice(OldPH->end(), BI.getParent(), BI.getIterator()); + BI.moveBefore(*OldPH, OldPH->end()); BI.setCondition(Cond); if (MSSAU) { // Temporarily clone the terminator, to make MSSA update cheaper by @@ -882,7 +880,7 @@ static bool unswitchTrivialSwitch(Loop &L, SwitchInst &SI, DominatorTree &DT, rewritePHINodesForUnswitchedExitBlock(*DefaultExitBB, *ParentBB, *OldPH); } else { auto *SplitBB = - SplitBlock(DefaultExitBB, &DefaultExitBB->front(), &DT, &LI, MSSAU); + SplitBlock(DefaultExitBB, DefaultExitBB->begin(), &DT, &LI, MSSAU); rewritePHINodesForExitAndUnswitchedBlocks(*DefaultExitBB, *SplitBB, *ParentBB, *OldPH, /*FullUnswitch*/ true); @@ -909,7 +907,7 @@ static bool unswitchTrivialSwitch(Loop &L, SwitchInst &SI, DominatorTree &DT, BasicBlock *&SplitExitBB = SplitExitBBMap[ExitBB]; if (!SplitExitBB) { // If this is the first time we see this, do the split and remember it. - SplitExitBB = SplitBlock(ExitBB, &ExitBB->front(), &DT, &LI, MSSAU); + SplitExitBB = SplitBlock(ExitBB, ExitBB->begin(), &DT, &LI, MSSAU); rewritePHINodesForExitAndUnswitchedBlocks(*ExitBB, *SplitExitBB, *ParentBB, *OldPH, /*FullUnswitch*/ true); @@ -1210,7 +1208,7 @@ static BasicBlock *buildClonedLoopBlocks( // place to merge the CFG, so split the exit first. This is always safe to // do because there cannot be any non-loop predecessors of a loop exit in // loop simplified form. - auto *MergeBB = SplitBlock(ExitBB, &ExitBB->front(), &DT, &LI, MSSAU); + auto *MergeBB = SplitBlock(ExitBB, ExitBB->begin(), &DT, &LI, MSSAU); // Rearrange the names to make it easier to write test cases by having the // exit block carry the suffix rather than the merge block carrying the @@ -1246,8 +1244,8 @@ static BasicBlock *buildClonedLoopBlocks( SE->forgetValue(&I); auto *MergePN = - PHINode::Create(I.getType(), /*NumReservedValues*/ 2, ".us-phi", - &*MergeBB->getFirstInsertionPt()); + PHINode::Create(I.getType(), /*NumReservedValues*/ 2, ".us-phi"); + MergePN->insertBefore(MergeBB->getFirstInsertionPt()); I.replaceAllUsesWith(MergePN); MergePN->addIncoming(&I, ExitBB); MergePN->addIncoming(&ClonedI, ClonedExitBB); @@ -1259,8 +1257,11 @@ static BasicBlock *buildClonedLoopBlocks( // everything available. Also, we have inserted new instructions which may // include assume intrinsics, so we update the assumption cache while // processing this. + Module *M = ClonedPH->getParent()->getParent(); for (auto *ClonedBB : NewBlocks) for (Instruction &I : *ClonedBB) { + RemapDPValueRange(M, I.getDbgValueRange(), VMap, + RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); RemapInstruction(&I, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); if (auto *II = dyn_cast<AssumeInst>(&I)) @@ -1684,13 +1685,12 @@ deleteDeadClonedBlocks(Loop &L, ArrayRef<BasicBlock *> ExitBlocks, BB->eraseFromParent(); } -static void -deleteDeadBlocksFromLoop(Loop &L, - SmallVectorImpl<BasicBlock *> &ExitBlocks, - DominatorTree &DT, LoopInfo &LI, - MemorySSAUpdater *MSSAU, - ScalarEvolution *SE, - function_ref<void(Loop &, StringRef)> DestroyLoopCB) { +static void deleteDeadBlocksFromLoop(Loop &L, + SmallVectorImpl<BasicBlock *> &ExitBlocks, + DominatorTree &DT, LoopInfo &LI, + MemorySSAUpdater *MSSAU, + ScalarEvolution *SE, + LPMUpdater &LoopUpdater) { // Find all the dead blocks tied to this loop, and remove them from their // successors. SmallSetVector<BasicBlock *, 8> DeadBlockSet; @@ -1740,7 +1740,7 @@ deleteDeadBlocksFromLoop(Loop &L, }) && "If the child loop header is dead all blocks in the child loop must " "be dead as well!"); - DestroyLoopCB(*ChildL, ChildL->getName()); + LoopUpdater.markLoopAsDeleted(*ChildL, ChildL->getName()); if (SE) SE->forgetBlockAndLoopDispositions(); LI.destroy(ChildL); @@ -2084,8 +2084,8 @@ static bool rebuildLoopAfterUnswitch(Loop &L, ArrayRef<BasicBlock *> ExitBlocks, ParentL->removeChildLoop(llvm::find(*ParentL, &L)); else LI.removeLoop(llvm::find(LI, &L)); - // markLoopAsDeleted for L should be triggered by the caller (it is typically - // done by using the UnswitchCB callback). + // markLoopAsDeleted for L should be triggered by the caller (it is + // typically done within postUnswitch). if (SE) SE->forgetBlockAndLoopDispositions(); LI.destroy(&L); @@ -2122,18 +2122,56 @@ void visitDomSubTree(DominatorTree &DT, BasicBlock *BB, CallableT Callable) { } while (!DomWorklist.empty()); } +void postUnswitch(Loop &L, LPMUpdater &U, StringRef LoopName, + bool CurrentLoopValid, bool PartiallyInvariant, + bool InjectedCondition, ArrayRef<Loop *> NewLoops) { + // If we did a non-trivial unswitch, we have added new (cloned) loops. + if (!NewLoops.empty()) + U.addSiblingLoops(NewLoops); + + // If the current loop remains valid, we should revisit it to catch any + // other unswitch opportunities. Otherwise, we need to mark it as deleted. + if (CurrentLoopValid) { + if (PartiallyInvariant) { + // Mark the new loop as partially unswitched, to avoid unswitching on + // the same condition again. + auto &Context = L.getHeader()->getContext(); + MDNode *DisableUnswitchMD = MDNode::get( + Context, + MDString::get(Context, "llvm.loop.unswitch.partial.disable")); + MDNode *NewLoopID = makePostTransformationMetadata( + Context, L.getLoopID(), {"llvm.loop.unswitch.partial"}, + {DisableUnswitchMD}); + L.setLoopID(NewLoopID); + } else if (InjectedCondition) { + // Do the same for injection of invariant conditions. + auto &Context = L.getHeader()->getContext(); + MDNode *DisableUnswitchMD = MDNode::get( + Context, + MDString::get(Context, "llvm.loop.unswitch.injection.disable")); + MDNode *NewLoopID = makePostTransformationMetadata( + Context, L.getLoopID(), {"llvm.loop.unswitch.injection"}, + {DisableUnswitchMD}); + L.setLoopID(NewLoopID); + } else + U.revisitCurrentLoop(); + } else + U.markLoopAsDeleted(L, LoopName); +} + static void unswitchNontrivialInvariants( Loop &L, Instruction &TI, ArrayRef<Value *> Invariants, IVConditionInfo &PartialIVInfo, DominatorTree &DT, LoopInfo &LI, - AssumptionCache &AC, - function_ref<void(bool, bool, bool, ArrayRef<Loop *>)> UnswitchCB, - ScalarEvolution *SE, MemorySSAUpdater *MSSAU, - function_ref<void(Loop &, StringRef)> DestroyLoopCB, bool InsertFreeze, - bool InjectedCondition) { + AssumptionCache &AC, ScalarEvolution *SE, MemorySSAUpdater *MSSAU, + LPMUpdater &LoopUpdater, bool InsertFreeze, bool InjectedCondition) { auto *ParentBB = TI.getParent(); BranchInst *BI = dyn_cast<BranchInst>(&TI); SwitchInst *SI = BI ? nullptr : cast<SwitchInst>(&TI); + // Save the current loop name in a variable so that we can report it even + // after it has been deleted. + std::string LoopName(L.getName()); + // We can only unswitch switches, conditional branches with an invariant // condition, or combining invariant conditions with an instruction or // partially invariant instructions. @@ -2296,7 +2334,7 @@ static void unswitchNontrivialInvariants( if (FullUnswitch) { // Splice the terminator from the original loop and rewrite its // successors. - SplitBB->splice(SplitBB->end(), ParentBB, TI.getIterator()); + TI.moveBefore(*SplitBB, SplitBB->end()); // Keep a clone of the terminator for MSSA updates. Instruction *NewTI = TI.clone(); @@ -2446,7 +2484,7 @@ static void unswitchNontrivialInvariants( // Now that our cloned loops have been built, we can update the original loop. // First we delete the dead blocks from it and then we rebuild the loop // structure taking these deletions into account. - deleteDeadBlocksFromLoop(L, ExitBlocks, DT, LI, MSSAU, SE,DestroyLoopCB); + deleteDeadBlocksFromLoop(L, ExitBlocks, DT, LI, MSSAU, SE, LoopUpdater); if (MSSAU && VerifyMemorySSA) MSSAU->getMemorySSA()->verifyMemorySSA(); @@ -2582,7 +2620,8 @@ static void unswitchNontrivialInvariants( for (Loop *UpdatedL : llvm::concat<Loop *>(NonChildClonedLoops, HoistedLoops)) if (UpdatedL->getParentLoop() == ParentL) SibLoops.push_back(UpdatedL); - UnswitchCB(IsStillLoop, PartiallyInvariant, InjectedCondition, SibLoops); + postUnswitch(L, LoopUpdater, LoopName, IsStillLoop, PartiallyInvariant, + InjectedCondition, SibLoops); if (MSSAU && VerifyMemorySSA) MSSAU->getMemorySSA()->verifyMemorySSA(); @@ -3429,12 +3468,11 @@ static bool shouldInsertFreeze(Loop &L, Instruction &TI, DominatorTree &DT, Cond, &AC, L.getLoopPreheader()->getTerminator(), &DT); } -static bool unswitchBestCondition( - Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, - AAResults &AA, TargetTransformInfo &TTI, - function_ref<void(bool, bool, bool, ArrayRef<Loop *>)> UnswitchCB, - ScalarEvolution *SE, MemorySSAUpdater *MSSAU, - function_ref<void(Loop &, StringRef)> DestroyLoopCB) { +static bool unswitchBestCondition(Loop &L, DominatorTree &DT, LoopInfo &LI, + AssumptionCache &AC, AAResults &AA, + TargetTransformInfo &TTI, ScalarEvolution *SE, + MemorySSAUpdater *MSSAU, + LPMUpdater &LoopUpdater) { // Collect all invariant conditions within this loop (as opposed to an inner // loop which would be handled when visiting that inner loop). SmallVector<NonTrivialUnswitchCandidate, 4> UnswitchCandidates; @@ -3497,8 +3535,8 @@ static bool unswitchBestCondition( LLVM_DEBUG(dbgs() << " Unswitching non-trivial (cost = " << Best.Cost << ") terminator: " << *Best.TI << "\n"); unswitchNontrivialInvariants(L, *Best.TI, Best.Invariants, PartialIVInfo, DT, - LI, AC, UnswitchCB, SE, MSSAU, DestroyLoopCB, - InsertFreeze, InjectedCondition); + LI, AC, SE, MSSAU, LoopUpdater, InsertFreeze, + InjectedCondition); return true; } @@ -3517,20 +3555,18 @@ static bool unswitchBestCondition( /// true, we will attempt to do non-trivial unswitching as well as trivial /// unswitching. /// -/// The `UnswitchCB` callback provided will be run after unswitching is -/// complete, with the first parameter set to `true` if the provided loop -/// remains a loop, and a list of new sibling loops created. +/// The `postUnswitch` function will be run after unswitching is complete +/// with information on whether or not the provided loop remains a loop and +/// a list of new sibling loops created. /// /// If `SE` is non-null, we will update that analysis based on the unswitching /// done. -static bool -unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, - AAResults &AA, TargetTransformInfo &TTI, bool Trivial, - bool NonTrivial, - function_ref<void(bool, bool, bool, ArrayRef<Loop *>)> UnswitchCB, - ScalarEvolution *SE, MemorySSAUpdater *MSSAU, - ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI, - function_ref<void(Loop &, StringRef)> DestroyLoopCB) { +static bool unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, + AssumptionCache &AC, AAResults &AA, + TargetTransformInfo &TTI, bool Trivial, + bool NonTrivial, ScalarEvolution *SE, + MemorySSAUpdater *MSSAU, ProfileSummaryInfo *PSI, + BlockFrequencyInfo *BFI, LPMUpdater &LoopUpdater) { assert(L.isRecursivelyLCSSAForm(DT, LI) && "Loops must be in LCSSA form before unswitching."); @@ -3542,8 +3578,9 @@ unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, if (Trivial && unswitchAllTrivialConditions(L, DT, LI, SE, MSSAU)) { // If we unswitched successfully we will want to clean up the loop before // processing it further so just mark it as unswitched and return. - UnswitchCB(/*CurrentLoopValid*/ true, /*PartiallyInvariant*/ false, - /*InjectedCondition*/ false, {}); + postUnswitch(L, LoopUpdater, L.getName(), + /*CurrentLoopValid*/ true, /*PartiallyInvariant*/ false, + /*InjectedCondition*/ false, {}); return true; } @@ -3612,8 +3649,7 @@ unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, // Try to unswitch the best invariant condition. We prefer this full unswitch to // a partial unswitch when possible below the threshold. - if (unswitchBestCondition(L, DT, LI, AC, AA, TTI, UnswitchCB, SE, MSSAU, - DestroyLoopCB)) + if (unswitchBestCondition(L, DT, LI, AC, AA, TTI, SE, MSSAU, LoopUpdater)) return true; // No other opportunities to unswitch. @@ -3633,52 +3669,6 @@ PreservedAnalyses SimpleLoopUnswitchPass::run(Loop &L, LoopAnalysisManager &AM, LLVM_DEBUG(dbgs() << "Unswitching loop in " << F.getName() << ": " << L << "\n"); - // Save the current loop name in a variable so that we can report it even - // after it has been deleted. - std::string LoopName = std::string(L.getName()); - - auto UnswitchCB = [&L, &U, &LoopName](bool CurrentLoopValid, - bool PartiallyInvariant, - bool InjectedCondition, - ArrayRef<Loop *> NewLoops) { - // If we did a non-trivial unswitch, we have added new (cloned) loops. - if (!NewLoops.empty()) - U.addSiblingLoops(NewLoops); - - // If the current loop remains valid, we should revisit it to catch any - // other unswitch opportunities. Otherwise, we need to mark it as deleted. - if (CurrentLoopValid) { - if (PartiallyInvariant) { - // Mark the new loop as partially unswitched, to avoid unswitching on - // the same condition again. - auto &Context = L.getHeader()->getContext(); - MDNode *DisableUnswitchMD = MDNode::get( - Context, - MDString::get(Context, "llvm.loop.unswitch.partial.disable")); - MDNode *NewLoopID = makePostTransformationMetadata( - Context, L.getLoopID(), {"llvm.loop.unswitch.partial"}, - {DisableUnswitchMD}); - L.setLoopID(NewLoopID); - } else if (InjectedCondition) { - // Do the same for injection of invariant conditions. - auto &Context = L.getHeader()->getContext(); - MDNode *DisableUnswitchMD = MDNode::get( - Context, - MDString::get(Context, "llvm.loop.unswitch.injection.disable")); - MDNode *NewLoopID = makePostTransformationMetadata( - Context, L.getLoopID(), {"llvm.loop.unswitch.injection"}, - {DisableUnswitchMD}); - L.setLoopID(NewLoopID); - } else - U.revisitCurrentLoop(); - } else - U.markLoopAsDeleted(L, LoopName); - }; - - auto DestroyLoopCB = [&U](Loop &L, StringRef Name) { - U.markLoopAsDeleted(L, Name); - }; - std::optional<MemorySSAUpdater> MSSAU; if (AR.MSSA) { MSSAU = MemorySSAUpdater(AR.MSSA); @@ -3686,8 +3676,7 @@ PreservedAnalyses SimpleLoopUnswitchPass::run(Loop &L, LoopAnalysisManager &AM, AR.MSSA->verifyMemorySSA(); } if (!unswitchLoop(L, AR.DT, AR.LI, AR.AC, AR.AA, AR.TTI, Trivial, NonTrivial, - UnswitchCB, &AR.SE, MSSAU ? &*MSSAU : nullptr, PSI, AR.BFI, - DestroyLoopCB)) + &AR.SE, MSSAU ? &*MSSAU : nullptr, PSI, AR.BFI, U)) return PreservedAnalyses::all(); if (AR.MSSA && VerifyMemorySSA) @@ -3713,105 +3702,3 @@ void SimpleLoopUnswitchPass::printPipeline( OS << (Trivial ? "" : "no-") << "trivial"; OS << '>'; } - -namespace { - -class SimpleLoopUnswitchLegacyPass : public LoopPass { - bool NonTrivial; - -public: - static char ID; // Pass ID, replacement for typeid - - explicit SimpleLoopUnswitchLegacyPass(bool NonTrivial = false) - : LoopPass(ID), NonTrivial(NonTrivial) { - initializeSimpleLoopUnswitchLegacyPassPass( - *PassRegistry::getPassRegistry()); - } - - bool runOnLoop(Loop *L, LPPassManager &LPM) override; - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired<AssumptionCacheTracker>(); - AU.addRequired<TargetTransformInfoWrapperPass>(); - AU.addRequired<MemorySSAWrapperPass>(); - AU.addPreserved<MemorySSAWrapperPass>(); - getLoopAnalysisUsage(AU); - } -}; - -} // end anonymous namespace - -bool SimpleLoopUnswitchLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) { - if (skipLoop(L)) - return false; - - Function &F = *L->getHeader()->getParent(); - - LLVM_DEBUG(dbgs() << "Unswitching loop in " << F.getName() << ": " << *L - << "\n"); - auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); - auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); - auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F); - auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults(); - auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F); - MemorySSA *MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA(); - MemorySSAUpdater MSSAU(MSSA); - - auto *SEWP = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>(); - auto *SE = SEWP ? &SEWP->getSE() : nullptr; - - auto UnswitchCB = [&L, &LPM](bool CurrentLoopValid, bool PartiallyInvariant, - bool InjectedCondition, - ArrayRef<Loop *> NewLoops) { - // If we did a non-trivial unswitch, we have added new (cloned) loops. - for (auto *NewL : NewLoops) - LPM.addLoop(*NewL); - - // If the current loop remains valid, re-add it to the queue. This is - // a little wasteful as we'll finish processing the current loop as well, - // but it is the best we can do in the old PM. - if (CurrentLoopValid) { - // If the current loop has been unswitched using a partially invariant - // condition or injected invariant condition, we should not re-add the - // current loop to avoid unswitching on the same condition again. - if (!PartiallyInvariant && !InjectedCondition) - LPM.addLoop(*L); - } else - LPM.markLoopAsDeleted(*L); - }; - - auto DestroyLoopCB = [&LPM](Loop &L, StringRef /* Name */) { - LPM.markLoopAsDeleted(L); - }; - - if (VerifyMemorySSA) - MSSA->verifyMemorySSA(); - bool Changed = - unswitchLoop(*L, DT, LI, AC, AA, TTI, true, NonTrivial, UnswitchCB, SE, - &MSSAU, nullptr, nullptr, DestroyLoopCB); - - if (VerifyMemorySSA) - MSSA->verifyMemorySSA(); - - // Historically this pass has had issues with the dominator tree so verify it - // in asserts builds. - assert(DT.verify(DominatorTree::VerificationLevel::Fast)); - - return Changed; -} - -char SimpleLoopUnswitchLegacyPass::ID = 0; -INITIALIZE_PASS_BEGIN(SimpleLoopUnswitchLegacyPass, "simple-loop-unswitch", - "Simple unswitch loops", false, false) -INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) -INITIALIZE_PASS_DEPENDENCY(LoopPass) -INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass) -INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) -INITIALIZE_PASS_END(SimpleLoopUnswitchLegacyPass, "simple-loop-unswitch", - "Simple unswitch loops", false, false) - -Pass *llvm::createSimpleLoopUnswitchLegacyPass(bool NonTrivial) { - return new SimpleLoopUnswitchLegacyPass(NonTrivial); -} |
