diff options
Diffstat (limited to 'contrib/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp')
-rw-r--r-- | contrib/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp | 125 |
1 files changed, 90 insertions, 35 deletions
diff --git a/contrib/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp b/contrib/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp index 95d7f8a..71980e8 100644 --- a/contrib/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/contrib/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -55,6 +55,7 @@ #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/Local.h" +#include "llvm/Transforms/Utils/LoopUtils.h" #include <algorithm> #include <map> #include <set> @@ -64,6 +65,7 @@ using namespace llvm; STATISTIC(NumBranches, "Number of branches unswitched"); STATISTIC(NumSwitches, "Number of switches unswitched"); +STATISTIC(NumGuards, "Number of guards unswitched"); STATISTIC(NumSelects , "Number of selects unswitched"); STATISTIC(NumTrivial , "Number of unswitches that are trivial"); STATISTIC(NumSimplify, "Number of simplifications of unswitched code"); @@ -187,6 +189,9 @@ namespace { BasicBlock *loopHeader; BasicBlock *loopPreheader; + bool SanitizeMemory; + LoopSafetyInfo SafetyInfo; + // LoopBlocks contains all of the basic blocks of the loop, including the // preheader of the loop, the body of the loop, and the exit blocks of the // loop, in that order. @@ -211,17 +216,8 @@ namespace { /// void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<AssumptionCacheTracker>(); - AU.addRequiredID(LoopSimplifyID); - AU.addPreservedID(LoopSimplifyID); - AU.addRequired<LoopInfoWrapperPass>(); - AU.addPreserved<LoopInfoWrapperPass>(); - AU.addRequiredID(LCSSAID); - AU.addPreservedID(LCSSAID); - AU.addRequired<DominatorTreeWrapperPass>(); - AU.addPreserved<DominatorTreeWrapperPass>(); - AU.addPreserved<ScalarEvolutionWrapperPass>(); AU.addRequired<TargetTransformInfoWrapperPass>(); - AU.addPreserved<GlobalsAAWrapperPass>(); + getLoopAnalysisUsage(AU); } private: @@ -382,11 +378,9 @@ void LUAnalysisCache::cloneData(const Loop *NewLoop, const Loop *OldLoop, char LoopUnswitch::ID = 0; INITIALIZE_PASS_BEGIN(LoopUnswitch, "loop-unswitch", "Unswitch loops", false, false) -INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) -INITIALIZE_PASS_DEPENDENCY(LoopSimplify) -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) -INITIALIZE_PASS_DEPENDENCY(LCSSA) +INITIALIZE_PASS_DEPENDENCY(LoopPass) +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_END(LoopUnswitch, "loop-unswitch", "Unswitch loops", false, false) @@ -396,7 +390,11 @@ Pass *llvm::createLoopUnswitchPass(bool Os) { /// Cond is a condition that occurs in L. If it is invariant in the loop, or has /// an invariant piece, return the invariant. Otherwise, return null. -static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed) { +static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed, + DenseMap<Value *, Value *> &Cache) { + auto CacheIt = Cache.find(Cond); + if (CacheIt != Cache.end()) + return CacheIt->second; // We started analyze new instruction, increment scanned instructions counter. ++TotalInsts; @@ -411,8 +409,10 @@ static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed) { // TODO: Handle: br (VARIANT|INVARIANT). // Hoist simple values out. - if (L->makeLoopInvariant(Cond, Changed)) + if (L->makeLoopInvariant(Cond, Changed)) { + Cache[Cond] = Cond; return Cond; + } if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Cond)) if (BO->getOpcode() == Instruction::And || @@ -420,17 +420,29 @@ static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed) { // If either the left or right side is invariant, we can unswitch on this, // which will cause the branch to go away in one loop and the condition to // simplify in the other one. - if (Value *LHS = FindLIVLoopCondition(BO->getOperand(0), L, Changed)) + if (Value *LHS = + FindLIVLoopCondition(BO->getOperand(0), L, Changed, Cache)) { + Cache[Cond] = LHS; return LHS; - if (Value *RHS = FindLIVLoopCondition(BO->getOperand(1), L, Changed)) + } + if (Value *RHS = + FindLIVLoopCondition(BO->getOperand(1), L, Changed, Cache)) { + Cache[Cond] = RHS; return RHS; + } } + Cache[Cond] = nullptr; return nullptr; } +static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed) { + DenseMap<Value *, Value *> Cache; + return FindLIVLoopCondition(Cond, L, Changed, Cache); +} + bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) { - if (skipOptnoneFunction(L)) + if (skipLoop(L)) return false; AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache( @@ -441,6 +453,10 @@ bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) { currentLoop = L; Function *F = currentLoop->getHeader()->getParent(); + SanitizeMemory = F->hasFnAttribute(Attribute::SanitizeMemory); + if (SanitizeMemory) + computeLoopSafetyInfo(&SafetyInfo, L); + EnabledPGO = F->getEntryCount().hasValue(); if (LoopUnswitchWithBlockFrequency && EnabledPGO) { @@ -499,17 +515,34 @@ bool LoopUnswitch::processCurrentLoop() { return true; } - // Do not unswitch loops containing convergent operations, as we might be - // making them control dependent on the unswitch value when they were not - // before. - // FIXME: This could be refined to only bail if the convergent operation is - // not already control-dependent on the unswitch value. + // Run through the instructions in the loop, keeping track of three things: + // + // - That we do not unswitch loops containing convergent operations, as we + // might be making them control dependent on the unswitch value when they + // were not before. + // FIXME: This could be refined to only bail if the convergent operation is + // not already control-dependent on the unswitch value. + // + // - That basic blocks in the loop contain invokes whose predecessor edges we + // cannot split. + // + // - The set of guard intrinsics encountered (these are non terminator + // instructions that are also profitable to be unswitched). + + SmallVector<IntrinsicInst *, 4> Guards; + for (const auto BB : currentLoop->blocks()) { for (auto &I : *BB) { auto CS = CallSite(&I); if (!CS) continue; if (CS.hasFnAttr(Attribute::Convergent)) return false; + if (auto *II = dyn_cast<InvokeInst>(&I)) + if (!II->getUnwindDest()->canSplitPredecessors()) + return false; + if (auto *II = dyn_cast<IntrinsicInst>(&I)) + if (II->getIntrinsicID() == Intrinsic::experimental_guard) + Guards.push_back(II); } } @@ -529,12 +562,36 @@ bool LoopUnswitch::processCurrentLoop() { return false; } + for (IntrinsicInst *Guard : Guards) { + Value *LoopCond = + FindLIVLoopCondition(Guard->getOperand(0), currentLoop, Changed); + if (LoopCond && + UnswitchIfProfitable(LoopCond, ConstantInt::getTrue(Context))) { + // NB! Unswitching (if successful) could have erased some of the + // instructions in Guards leaving dangling pointers there. This is fine + // because we're returning now, and won't look at Guards again. + ++NumGuards; + return true; + } + } + // Loop over all of the basic blocks in the loop. If we find an interior // block that is branching on a loop-invariant condition, we can unswitch this // loop. for (Loop::block_iterator I = currentLoop->block_begin(), E = currentLoop->block_end(); I != E; ++I) { TerminatorInst *TI = (*I)->getTerminator(); + + // Unswitching on a potentially uninitialized predicate is not + // MSan-friendly. Limit this to the cases when the original predicate is + // guaranteed to execute, to avoid creating a use-of-uninitialized-value + // in the code that did not have one. + // This is a workaround for the discrepancy between LLVM IR and MSan + // semantics. See PR28054 for more details. + if (SanitizeMemory && + !isGuaranteedToExecute(*TI, DT, currentLoop, &SafetyInfo)) + continue; + if (BranchInst *BI = dyn_cast<BranchInst>(TI)) { // If this isn't branching on an invariant condition, we can't unswitch // it. @@ -628,8 +685,8 @@ static bool isTrivialLoopExitBlockHelper(Loop *L, BasicBlock *BB, // Okay, everything after this looks good, check to make sure that this block // doesn't include any side effects. - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) - if (I->mayHaveSideEffects()) + for (Instruction &I : *BB) + if (I.mayHaveSideEffects()) return false; return true; @@ -679,8 +736,8 @@ static Loop *CloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM, New.addBasicBlockToLoop(cast<BasicBlock>(VM[*I]), *LI); // Add all of the subloops to the new loop. - for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I) - CloneLoop(*I, &New, VM, LI, LPM); + for (Loop *I : *L) + CloneLoop(I, &New, VM, LI, LPM); return &New; } @@ -1075,10 +1132,9 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val, // Rewrite the code to refer to itself. for (unsigned i = 0, e = NewBlocks.size(); i != e; ++i) - for (BasicBlock::iterator I = NewBlocks[i]->begin(), - E = NewBlocks[i]->end(); I != E; ++I) - RemapInstruction(&*I, VMap, - RF_NoModuleLevelChanges | RF_IgnoreMissingEntries); + for (Instruction &I : *NewBlocks[i]) + RemapInstruction(&I, VMap, + RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); // Rewrite the original preheader to select between versions of the loop. BranchInst *OldBR = cast<BranchInst>(loopPreheader->getTerminator()); @@ -1180,9 +1236,8 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC, Worklist.push_back(UI); } - for (std::vector<Instruction*>::iterator UI = Worklist.begin(), - UE = Worklist.end(); UI != UE; ++UI) - (*UI)->replaceUsesOfWith(LIC, Replacement); + for (Instruction *UI : Worklist) + UI->replaceUsesOfWith(LIC, Replacement); SimplifyCode(Worklist, L); return; |