diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp index ad7d34b61470..633d077e6492 100644 --- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -2126,9 +2126,10 @@ static void unswitchNontrivialInvariants( Loop &L, Instruction &TI, ArrayRef<Value *> Invariants, IVConditionInfo &PartialIVInfo, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, - function_ref<void(bool, bool, ArrayRef<Loop *>)> UnswitchCB, + function_ref<void(bool, bool, bool, ArrayRef<Loop *>)> UnswitchCB, ScalarEvolution *SE, MemorySSAUpdater *MSSAU, - function_ref<void(Loop &, StringRef)> DestroyLoopCB, bool InsertFreeze) { + function_ref<void(Loop &, StringRef)> DestroyLoopCB, bool InsertFreeze, + bool InjectedCondition) { auto *ParentBB = TI.getParent(); BranchInst *BI = dyn_cast<BranchInst>(&TI); SwitchInst *SI = BI ? nullptr : cast<SwitchInst>(&TI); @@ -2581,7 +2582,7 @@ static void unswitchNontrivialInvariants( for (Loop *UpdatedL : llvm::concat<Loop *>(NonChildClonedLoops, HoistedLoops)) if (UpdatedL->getParentLoop() == ParentL) SibLoops.push_back(UpdatedL); - UnswitchCB(IsStillLoop, PartiallyInvariant, SibLoops); + UnswitchCB(IsStillLoop, PartiallyInvariant, InjectedCondition, SibLoops); if (MSSAU && VerifyMemorySSA) MSSAU->getMemorySSA()->verifyMemorySSA(); @@ -2979,13 +2980,6 @@ static bool shouldTryInjectInvariantCondition( /// the metadata. bool shouldTryInjectBasingOnMetadata(const BranchInst *BI, const BasicBlock *TakenSucc) { - // Skip branches that have already been unswithed this way. After successful - // unswitching of injected condition, we will still have a copy of this loop - // which looks exactly the same as original one. To prevent the 2nd attempt - // of unswitching it in the same pass, mark this branch as "nothing to do - // here". - if (BI->hasMetadata("llvm.invariant.condition.injection.disabled")) - return false; SmallVector<uint32_t> Weights; if (!extractBranchWeights(*BI, Weights)) return false; @@ -3060,7 +3054,6 @@ injectPendingInvariantConditions(NonTrivialUnswitchCandidate Candidate, Loop &L, auto *InjectedCond = ICmpInst::Create(Instruction::ICmp, Pred, LHS, RHS, "injected.cond", Preheader->getTerminator()); - auto *OldCond = TI->getCondition(); BasicBlock *CheckBlock = BasicBlock::Create(Ctx, BB->getName() + ".check", BB->getParent(), InLoopSucc); @@ -3069,12 +3062,9 @@ injectPendingInvariantConditions(NonTrivialUnswitchCandidate Candidate, Loop &L, Builder.CreateCondBr(InjectedCond, InLoopSucc, CheckBlock); Builder.SetInsertPoint(CheckBlock); - auto *NewTerm = Builder.CreateCondBr(OldCond, InLoopSucc, OutOfLoopSucc); - + Builder.CreateCondBr(TI->getCondition(), TI->getSuccessor(0), + TI->getSuccessor(1)); TI->eraseFromParent(); - // Prevent infinite unswitching. - NewTerm->setMetadata("llvm.invariant.condition.injection.disabled", - MDNode::get(BB->getContext(), {})); // Fixup phis. for (auto &I : *InLoopSucc) { @@ -3442,7 +3432,7 @@ static bool shouldInsertFreeze(Loop &L, Instruction &TI, DominatorTree &DT, static bool unswitchBestCondition( Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, AAResults &AA, TargetTransformInfo &TTI, - function_ref<void(bool, bool, ArrayRef<Loop *>)> UnswitchCB, + function_ref<void(bool, bool, bool, ArrayRef<Loop *>)> UnswitchCB, ScalarEvolution *SE, MemorySSAUpdater *MSSAU, function_ref<void(Loop &, StringRef)> DestroyLoopCB) { // Collect all invariant conditions within this loop (as opposed to an inner @@ -3452,9 +3442,10 @@ static bool unswitchBestCondition( Instruction *PartialIVCondBranch = nullptr; collectUnswitchCandidates(UnswitchCandidates, PartialIVInfo, PartialIVCondBranch, L, LI, AA, MSSAU); - collectUnswitchCandidatesWithInjections(UnswitchCandidates, PartialIVInfo, - PartialIVCondBranch, L, DT, LI, AA, - MSSAU); + if (!findOptionMDForLoop(&L, "llvm.loop.unswitch.injection.disable")) + collectUnswitchCandidatesWithInjections(UnswitchCandidates, PartialIVInfo, + PartialIVCondBranch, L, DT, LI, AA, + MSSAU); // If we didn't find any candidates, we're done. if (UnswitchCandidates.empty()) return false; @@ -3475,8 +3466,11 @@ static bool unswitchBestCondition( return false; } - if (Best.hasPendingInjection()) + bool InjectedCondition = false; + if (Best.hasPendingInjection()) { Best = injectPendingInvariantConditions(Best, L, DT, LI, AC, MSSAU); + InjectedCondition = true; + } assert(!Best.hasPendingInjection() && "All injections should have been done by now!"); @@ -3504,7 +3498,7 @@ static bool unswitchBestCondition( << ") terminator: " << *Best.TI << "\n"); unswitchNontrivialInvariants(L, *Best.TI, Best.Invariants, PartialIVInfo, DT, LI, AC, UnswitchCB, SE, MSSAU, DestroyLoopCB, - InsertFreeze); + InsertFreeze, InjectedCondition); return true; } @@ -3533,7 +3527,7 @@ static bool unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, AAResults &AA, TargetTransformInfo &TTI, bool Trivial, bool NonTrivial, - function_ref<void(bool, bool, ArrayRef<Loop *>)> UnswitchCB, + function_ref<void(bool, bool, bool, ArrayRef<Loop *>)> UnswitchCB, ScalarEvolution *SE, MemorySSAUpdater *MSSAU, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI, function_ref<void(Loop &, StringRef)> DestroyLoopCB) { @@ -3548,7 +3542,8 @@ 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, false, {}); + UnswitchCB(/*CurrentLoopValid*/ true, /*PartiallyInvariant*/ false, + /*InjectedCondition*/ false, {}); return true; } @@ -3644,6 +3639,7 @@ PreservedAnalyses SimpleLoopUnswitchPass::run(Loop &L, LoopAnalysisManager &AM, 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()) @@ -3663,6 +3659,16 @@ PreservedAnalyses SimpleLoopUnswitchPass::run(Loop &L, LoopAnalysisManager &AM, 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 @@ -3755,6 +3761,7 @@ bool SimpleLoopUnswitchLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) { 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) @@ -3765,9 +3772,9 @@ bool SimpleLoopUnswitchLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) { // 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, we should not re-add the current loop to avoid unswitching - // on the same condition again. - if (!PartiallyInvariant) + // 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); |
