18fb3d57eSArtur Pilipenko //===-- LoopPredication.cpp - Guard based loop predication pass -----------===// 28fb3d57eSArtur Pilipenko // 38fb3d57eSArtur Pilipenko // The LLVM Compiler Infrastructure 48fb3d57eSArtur Pilipenko // 58fb3d57eSArtur Pilipenko // This file is distributed under the University of Illinois Open Source 68fb3d57eSArtur Pilipenko // License. See LICENSE.TXT for details. 78fb3d57eSArtur Pilipenko // 88fb3d57eSArtur Pilipenko //===----------------------------------------------------------------------===// 98fb3d57eSArtur Pilipenko // 108fb3d57eSArtur Pilipenko // The LoopPredication pass tries to convert loop variant range checks to loop 118fb3d57eSArtur Pilipenko // invariant by widening checks across loop iterations. For example, it will 128fb3d57eSArtur Pilipenko // convert 138fb3d57eSArtur Pilipenko // 148fb3d57eSArtur Pilipenko // for (i = 0; i < n; i++) { 158fb3d57eSArtur Pilipenko // guard(i < len); 168fb3d57eSArtur Pilipenko // ... 178fb3d57eSArtur Pilipenko // } 188fb3d57eSArtur Pilipenko // 198fb3d57eSArtur Pilipenko // to 208fb3d57eSArtur Pilipenko // 218fb3d57eSArtur Pilipenko // for (i = 0; i < n; i++) { 228fb3d57eSArtur Pilipenko // guard(n - 1 < len); 238fb3d57eSArtur Pilipenko // ... 248fb3d57eSArtur Pilipenko // } 258fb3d57eSArtur Pilipenko // 268fb3d57eSArtur Pilipenko // After this transformation the condition of the guard is loop invariant, so 278fb3d57eSArtur Pilipenko // loop-unswitch can later unswitch the loop by this condition which basically 288fb3d57eSArtur Pilipenko // predicates the loop by the widened condition: 298fb3d57eSArtur Pilipenko // 308fb3d57eSArtur Pilipenko // if (n - 1 < len) 318fb3d57eSArtur Pilipenko // for (i = 0; i < n; i++) { 328fb3d57eSArtur Pilipenko // ... 338fb3d57eSArtur Pilipenko // } 348fb3d57eSArtur Pilipenko // else 358fb3d57eSArtur Pilipenko // deoptimize 368fb3d57eSArtur Pilipenko // 37889dc1e3SArtur Pilipenko // It's tempting to rely on SCEV here, but it has proven to be problematic. 38889dc1e3SArtur Pilipenko // Generally the facts SCEV provides about the increment step of add 39889dc1e3SArtur Pilipenko // recurrences are true if the backedge of the loop is taken, which implicitly 40889dc1e3SArtur Pilipenko // assumes that the guard doesn't fail. Using these facts to optimize the 41889dc1e3SArtur Pilipenko // guard results in a circular logic where the guard is optimized under the 42889dc1e3SArtur Pilipenko // assumption that it never fails. 43889dc1e3SArtur Pilipenko // 44889dc1e3SArtur Pilipenko // For example, in the loop below the induction variable will be marked as nuw 45889dc1e3SArtur Pilipenko // basing on the guard. Basing on nuw the guard predicate will be considered 46889dc1e3SArtur Pilipenko // monotonic. Given a monotonic condition it's tempting to replace the induction 47889dc1e3SArtur Pilipenko // variable in the condition with its value on the last iteration. But this 48889dc1e3SArtur Pilipenko // transformation is not correct, e.g. e = 4, b = 5 breaks the loop. 49889dc1e3SArtur Pilipenko // 50889dc1e3SArtur Pilipenko // for (int i = b; i != e; i++) 51889dc1e3SArtur Pilipenko // guard(i u< len) 52889dc1e3SArtur Pilipenko // 53889dc1e3SArtur Pilipenko // One of the ways to reason about this problem is to use an inductive proof 54889dc1e3SArtur Pilipenko // approach. Given the loop: 55889dc1e3SArtur Pilipenko // 56889dc1e3SArtur Pilipenko // if (B(Start)) { 57889dc1e3SArtur Pilipenko // do { 58889dc1e3SArtur Pilipenko // I = PHI(Start, I.INC) 59889dc1e3SArtur Pilipenko // I.INC = I + Step 60889dc1e3SArtur Pilipenko // guard(G(I)); 61889dc1e3SArtur Pilipenko // } while (B(I.INC)); 62889dc1e3SArtur Pilipenko // } 63889dc1e3SArtur Pilipenko // 64889dc1e3SArtur Pilipenko // where B(x) and G(x) are predicates that map integers to booleans, we want a 65889dc1e3SArtur Pilipenko // loop invariant expression M such the following program has the same semantics 66889dc1e3SArtur Pilipenko // as the above: 67889dc1e3SArtur Pilipenko // 68889dc1e3SArtur Pilipenko // if (B(Start)) { 69889dc1e3SArtur Pilipenko // do { 70889dc1e3SArtur Pilipenko // I = PHI(Start, I.INC) 71889dc1e3SArtur Pilipenko // I.INC = I + Step 72889dc1e3SArtur Pilipenko // guard(G(Start) && M); 73889dc1e3SArtur Pilipenko // } while (B(I.INC)); 74889dc1e3SArtur Pilipenko // } 75889dc1e3SArtur Pilipenko // 76889dc1e3SArtur Pilipenko // One solution for M is M = forall X . (G(X) && B(X + Step)) => G(X + Step) 77889dc1e3SArtur Pilipenko // 78889dc1e3SArtur Pilipenko // Informal proof that the transformation above is correct: 79889dc1e3SArtur Pilipenko // 80889dc1e3SArtur Pilipenko // By the definition of guards we can rewrite the guard condition to: 81889dc1e3SArtur Pilipenko // G(I) && G(Start) && M 82889dc1e3SArtur Pilipenko // 83889dc1e3SArtur Pilipenko // Let's prove that for each iteration of the loop: 84889dc1e3SArtur Pilipenko // G(Start) && M => G(I) 85889dc1e3SArtur Pilipenko // And the condition above can be simplified to G(Start) && M. 86889dc1e3SArtur Pilipenko // 87889dc1e3SArtur Pilipenko // Induction base. 88889dc1e3SArtur Pilipenko // G(Start) && M => G(Start) 89889dc1e3SArtur Pilipenko // 90889dc1e3SArtur Pilipenko // Induction step. Assuming G(Start) && M => G(I) on the subsequent 91889dc1e3SArtur Pilipenko // iteration: 92889dc1e3SArtur Pilipenko // 93889dc1e3SArtur Pilipenko // B(I + Step) is true because it's the backedge condition. 94889dc1e3SArtur Pilipenko // G(I) is true because the backedge is guarded by this condition. 95889dc1e3SArtur Pilipenko // 96889dc1e3SArtur Pilipenko // So M = forall X . (G(X) && B(X + Step)) => G(X + Step) implies 97889dc1e3SArtur Pilipenko // G(I + Step). 98889dc1e3SArtur Pilipenko // 99889dc1e3SArtur Pilipenko // Note that we can use anything stronger than M, i.e. any condition which 100889dc1e3SArtur Pilipenko // implies M. 101889dc1e3SArtur Pilipenko // 102889dc1e3SArtur Pilipenko // For now the transformation is limited to the following case: 103b4527e1cSArtur Pilipenko // * The loop has a single latch with the condition of the form: 104b4527e1cSArtur Pilipenko // ++i <pred> latchLimit, where <pred> is u<, u<=, s<, or s<=. 105889dc1e3SArtur Pilipenko // * The step of the IV used in the latch condition is 1. 106889dc1e3SArtur Pilipenko // * The IV of the latch condition is the same as the post increment IV of the 107889dc1e3SArtur Pilipenko // guard condition. 108b4527e1cSArtur Pilipenko // * The guard condition is 109b4527e1cSArtur Pilipenko // i u< guardLimit. 110889dc1e3SArtur Pilipenko // 111b4527e1cSArtur Pilipenko // For the ult latch comparison case M is: 112889dc1e3SArtur Pilipenko // forall X . X u< guardLimit && (X + 1) u< latchLimit => 113889dc1e3SArtur Pilipenko // (X + 1) u< guardLimit 114889dc1e3SArtur Pilipenko // 115889dc1e3SArtur Pilipenko // This is true if latchLimit u<= guardLimit since then 116889dc1e3SArtur Pilipenko // (X + 1) u< latchLimit u<= guardLimit == (X + 1) u< guardLimit. 117889dc1e3SArtur Pilipenko // 118b4527e1cSArtur Pilipenko // So for ult condition the widened condition is: 119889dc1e3SArtur Pilipenko // i.start u< guardLimit && latchLimit u<= guardLimit 120b4527e1cSArtur Pilipenko // Similarly for ule condition the widened condition is: 121b4527e1cSArtur Pilipenko // i.start u< guardLimit && latchLimit u< guardLimit 122889dc1e3SArtur Pilipenko // 123889dc1e3SArtur Pilipenko // For the signed latch comparison case M is: 124889dc1e3SArtur Pilipenko // forall X . X u< guardLimit && (X + 1) s< latchLimit => 125889dc1e3SArtur Pilipenko // (X + 1) u< guardLimit 126889dc1e3SArtur Pilipenko // 127889dc1e3SArtur Pilipenko // The only way the antecedent can be true and the consequent can be false is 128889dc1e3SArtur Pilipenko // if 129889dc1e3SArtur Pilipenko // X == guardLimit - 1 130889dc1e3SArtur Pilipenko // (and guardLimit is non-zero, but we won't use this latter fact). 131889dc1e3SArtur Pilipenko // If X == guardLimit - 1 then the second half of the antecedent is 132889dc1e3SArtur Pilipenko // guardLimit s< latchLimit 133889dc1e3SArtur Pilipenko // and its negation is 134889dc1e3SArtur Pilipenko // latchLimit s<= guardLimit. 135889dc1e3SArtur Pilipenko // 136889dc1e3SArtur Pilipenko // In other words, if latchLimit s<= guardLimit then: 137889dc1e3SArtur Pilipenko // (the ranges below are written in ConstantRange notation, where [A, B) is the 138889dc1e3SArtur Pilipenko // set for (I = A; I != B; I++ /*maywrap*/) yield(I);) 139889dc1e3SArtur Pilipenko // 140889dc1e3SArtur Pilipenko // forall X . X u< guardLimit && (X + 1) s< latchLimit => (X + 1) u< guardLimit 141889dc1e3SArtur Pilipenko // == forall X . X u< guardLimit && (X + 1) s< guardLimit => (X + 1) u< guardLimit 142889dc1e3SArtur Pilipenko // == forall X . X in [0, guardLimit) && (X + 1) in [INT_MIN, guardLimit) => (X + 1) in [0, guardLimit) 143889dc1e3SArtur Pilipenko // == forall X . X in [0, guardLimit) && X in [INT_MAX, guardLimit-1) => X in [-1, guardLimit-1) 144889dc1e3SArtur Pilipenko // == forall X . X in [0, guardLimit-1) => X in [-1, guardLimit-1) 145889dc1e3SArtur Pilipenko // == true 146889dc1e3SArtur Pilipenko // 147889dc1e3SArtur Pilipenko // So the widened condition is: 148889dc1e3SArtur Pilipenko // i.start u< guardLimit && latchLimit s<= guardLimit 149b4527e1cSArtur Pilipenko // Similarly for sle condition the widened condition is: 150b4527e1cSArtur Pilipenko // i.start u< guardLimit && latchLimit s< guardLimit 151889dc1e3SArtur Pilipenko // 1528fb3d57eSArtur Pilipenko //===----------------------------------------------------------------------===// 1538fb3d57eSArtur Pilipenko 1548fb3d57eSArtur Pilipenko #include "llvm/Transforms/Scalar/LoopPredication.h" 1558fb3d57eSArtur Pilipenko #include "llvm/Analysis/LoopInfo.h" 1568fb3d57eSArtur Pilipenko #include "llvm/Analysis/LoopPass.h" 1578fb3d57eSArtur Pilipenko #include "llvm/Analysis/ScalarEvolution.h" 1588fb3d57eSArtur Pilipenko #include "llvm/Analysis/ScalarEvolutionExpander.h" 1598fb3d57eSArtur Pilipenko #include "llvm/Analysis/ScalarEvolutionExpressions.h" 1608fb3d57eSArtur Pilipenko #include "llvm/IR/Function.h" 1618fb3d57eSArtur Pilipenko #include "llvm/IR/GlobalValue.h" 1628fb3d57eSArtur Pilipenko #include "llvm/IR/IntrinsicInst.h" 1638fb3d57eSArtur Pilipenko #include "llvm/IR/Module.h" 1648fb3d57eSArtur Pilipenko #include "llvm/IR/PatternMatch.h" 1656bda14b3SChandler Carruth #include "llvm/Pass.h" 1668fb3d57eSArtur Pilipenko #include "llvm/Support/Debug.h" 1678fb3d57eSArtur Pilipenko #include "llvm/Transforms/Scalar.h" 1688fb3d57eSArtur Pilipenko #include "llvm/Transforms/Utils/LoopUtils.h" 1698fb3d57eSArtur Pilipenko 1708fb3d57eSArtur Pilipenko #define DEBUG_TYPE "loop-predication" 1718fb3d57eSArtur Pilipenko 1728fb3d57eSArtur Pilipenko using namespace llvm; 1738fb3d57eSArtur Pilipenko 1748fb3d57eSArtur Pilipenko namespace { 1758fb3d57eSArtur Pilipenko class LoopPredication { 176a6c27804SArtur Pilipenko /// Represents an induction variable check: 177a6c27804SArtur Pilipenko /// icmp Pred, <induction variable>, <loop invariant limit> 178a6c27804SArtur Pilipenko struct LoopICmp { 179a6c27804SArtur Pilipenko ICmpInst::Predicate Pred; 180a6c27804SArtur Pilipenko const SCEVAddRecExpr *IV; 181a6c27804SArtur Pilipenko const SCEV *Limit; 182c488dfabSArtur Pilipenko LoopICmp(ICmpInst::Predicate Pred, const SCEVAddRecExpr *IV, 183c488dfabSArtur Pilipenko const SCEV *Limit) 184a6c27804SArtur Pilipenko : Pred(Pred), IV(IV), Limit(Limit) {} 185a6c27804SArtur Pilipenko LoopICmp() {} 186a6c27804SArtur Pilipenko }; 187c488dfabSArtur Pilipenko 188c488dfabSArtur Pilipenko ScalarEvolution *SE; 189c488dfabSArtur Pilipenko 190c488dfabSArtur Pilipenko Loop *L; 191c488dfabSArtur Pilipenko const DataLayout *DL; 192c488dfabSArtur Pilipenko BasicBlock *Preheader; 193889dc1e3SArtur Pilipenko LoopICmp LatchCheck; 194c488dfabSArtur Pilipenko 195889dc1e3SArtur Pilipenko Optional<LoopICmp> parseLoopICmp(ICmpInst *ICI) { 196889dc1e3SArtur Pilipenko return parseLoopICmp(ICI->getPredicate(), ICI->getOperand(0), 197889dc1e3SArtur Pilipenko ICI->getOperand(1)); 198889dc1e3SArtur Pilipenko } 199889dc1e3SArtur Pilipenko Optional<LoopICmp> parseLoopICmp(ICmpInst::Predicate Pred, Value *LHS, 200889dc1e3SArtur Pilipenko Value *RHS); 201889dc1e3SArtur Pilipenko 202889dc1e3SArtur Pilipenko Optional<LoopICmp> parseLoopLatchICmp(); 203a6c27804SArtur Pilipenko 2046780ba65SArtur Pilipenko Value *expandCheck(SCEVExpander &Expander, IRBuilder<> &Builder, 2056780ba65SArtur Pilipenko ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, 2066780ba65SArtur Pilipenko Instruction *InsertAt); 2076780ba65SArtur Pilipenko 2088fb3d57eSArtur Pilipenko Optional<Value *> widenICmpRangeCheck(ICmpInst *ICI, SCEVExpander &Expander, 2098fb3d57eSArtur Pilipenko IRBuilder<> &Builder); 2108fb3d57eSArtur Pilipenko bool widenGuardConditions(IntrinsicInst *II, SCEVExpander &Expander); 2118fb3d57eSArtur Pilipenko 2128fb3d57eSArtur Pilipenko public: 2138fb3d57eSArtur Pilipenko LoopPredication(ScalarEvolution *SE) : SE(SE){}; 2148fb3d57eSArtur Pilipenko bool runOnLoop(Loop *L); 2158fb3d57eSArtur Pilipenko }; 2168fb3d57eSArtur Pilipenko 2178fb3d57eSArtur Pilipenko class LoopPredicationLegacyPass : public LoopPass { 2188fb3d57eSArtur Pilipenko public: 2198fb3d57eSArtur Pilipenko static char ID; 2208fb3d57eSArtur Pilipenko LoopPredicationLegacyPass() : LoopPass(ID) { 2218fb3d57eSArtur Pilipenko initializeLoopPredicationLegacyPassPass(*PassRegistry::getPassRegistry()); 2228fb3d57eSArtur Pilipenko } 2238fb3d57eSArtur Pilipenko 2248fb3d57eSArtur Pilipenko void getAnalysisUsage(AnalysisUsage &AU) const override { 2258fb3d57eSArtur Pilipenko getLoopAnalysisUsage(AU); 2268fb3d57eSArtur Pilipenko } 2278fb3d57eSArtur Pilipenko 2288fb3d57eSArtur Pilipenko bool runOnLoop(Loop *L, LPPassManager &LPM) override { 2298fb3d57eSArtur Pilipenko if (skipLoop(L)) 2308fb3d57eSArtur Pilipenko return false; 2318fb3d57eSArtur Pilipenko auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE(); 2328fb3d57eSArtur Pilipenko LoopPredication LP(SE); 2338fb3d57eSArtur Pilipenko return LP.runOnLoop(L); 2348fb3d57eSArtur Pilipenko } 2358fb3d57eSArtur Pilipenko }; 2368fb3d57eSArtur Pilipenko 2378fb3d57eSArtur Pilipenko char LoopPredicationLegacyPass::ID = 0; 2388fb3d57eSArtur Pilipenko } // end namespace llvm 2398fb3d57eSArtur Pilipenko 2408fb3d57eSArtur Pilipenko INITIALIZE_PASS_BEGIN(LoopPredicationLegacyPass, "loop-predication", 2418fb3d57eSArtur Pilipenko "Loop predication", false, false) 2428fb3d57eSArtur Pilipenko INITIALIZE_PASS_DEPENDENCY(LoopPass) 2438fb3d57eSArtur Pilipenko INITIALIZE_PASS_END(LoopPredicationLegacyPass, "loop-predication", 2448fb3d57eSArtur Pilipenko "Loop predication", false, false) 2458fb3d57eSArtur Pilipenko 2468fb3d57eSArtur Pilipenko Pass *llvm::createLoopPredicationPass() { 2478fb3d57eSArtur Pilipenko return new LoopPredicationLegacyPass(); 2488fb3d57eSArtur Pilipenko } 2498fb3d57eSArtur Pilipenko 2508fb3d57eSArtur Pilipenko PreservedAnalyses LoopPredicationPass::run(Loop &L, LoopAnalysisManager &AM, 2518fb3d57eSArtur Pilipenko LoopStandardAnalysisResults &AR, 2528fb3d57eSArtur Pilipenko LPMUpdater &U) { 2538fb3d57eSArtur Pilipenko LoopPredication LP(&AR.SE); 2548fb3d57eSArtur Pilipenko if (!LP.runOnLoop(&L)) 2558fb3d57eSArtur Pilipenko return PreservedAnalyses::all(); 2568fb3d57eSArtur Pilipenko 2578fb3d57eSArtur Pilipenko return getLoopPassPreservedAnalyses(); 2588fb3d57eSArtur Pilipenko } 2598fb3d57eSArtur Pilipenko 260a6c27804SArtur Pilipenko Optional<LoopPredication::LoopICmp> 261889dc1e3SArtur Pilipenko LoopPredication::parseLoopICmp(ICmpInst::Predicate Pred, Value *LHS, 262889dc1e3SArtur Pilipenko Value *RHS) { 263a6c27804SArtur Pilipenko const SCEV *LHSS = SE->getSCEV(LHS); 264a6c27804SArtur Pilipenko if (isa<SCEVCouldNotCompute>(LHSS)) 265a6c27804SArtur Pilipenko return None; 266a6c27804SArtur Pilipenko const SCEV *RHSS = SE->getSCEV(RHS); 267a6c27804SArtur Pilipenko if (isa<SCEVCouldNotCompute>(RHSS)) 268a6c27804SArtur Pilipenko return None; 269a6c27804SArtur Pilipenko 270a6c27804SArtur Pilipenko // Canonicalize RHS to be loop invariant bound, LHS - a loop computable IV 271a6c27804SArtur Pilipenko if (SE->isLoopInvariant(LHSS, L)) { 272a6c27804SArtur Pilipenko std::swap(LHS, RHS); 273a6c27804SArtur Pilipenko std::swap(LHSS, RHSS); 274a6c27804SArtur Pilipenko Pred = ICmpInst::getSwappedPredicate(Pred); 275a6c27804SArtur Pilipenko } 276a6c27804SArtur Pilipenko 277a6c27804SArtur Pilipenko const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(LHSS); 278a6c27804SArtur Pilipenko if (!AR || AR->getLoop() != L) 279a6c27804SArtur Pilipenko return None; 280a6c27804SArtur Pilipenko 281a6c27804SArtur Pilipenko return LoopICmp(Pred, AR, RHSS); 282a6c27804SArtur Pilipenko } 283a6c27804SArtur Pilipenko 2846780ba65SArtur Pilipenko Value *LoopPredication::expandCheck(SCEVExpander &Expander, 2856780ba65SArtur Pilipenko IRBuilder<> &Builder, 2866780ba65SArtur Pilipenko ICmpInst::Predicate Pred, const SCEV *LHS, 2876780ba65SArtur Pilipenko const SCEV *RHS, Instruction *InsertAt) { 288889dc1e3SArtur Pilipenko // TODO: we can check isLoopEntryGuardedByCond before emitting the check 289889dc1e3SArtur Pilipenko 2906780ba65SArtur Pilipenko Type *Ty = LHS->getType(); 2916780ba65SArtur Pilipenko assert(Ty == RHS->getType() && "expandCheck operands have different types?"); 292*ead69ee4SArtur Pilipenko 293*ead69ee4SArtur Pilipenko if (SE->isLoopEntryGuardedByCond(L, Pred, LHS, RHS)) 294*ead69ee4SArtur Pilipenko return Builder.getTrue(); 295*ead69ee4SArtur Pilipenko 2966780ba65SArtur Pilipenko Value *LHSV = Expander.expandCodeFor(LHS, Ty, InsertAt); 2976780ba65SArtur Pilipenko Value *RHSV = Expander.expandCodeFor(RHS, Ty, InsertAt); 2986780ba65SArtur Pilipenko return Builder.CreateICmp(Pred, LHSV, RHSV); 2996780ba65SArtur Pilipenko } 3006780ba65SArtur Pilipenko 3018fb3d57eSArtur Pilipenko /// If ICI can be widened to a loop invariant condition emits the loop 3028fb3d57eSArtur Pilipenko /// invariant condition in the loop preheader and return it, otherwise 3038fb3d57eSArtur Pilipenko /// returns None. 3048fb3d57eSArtur Pilipenko Optional<Value *> LoopPredication::widenICmpRangeCheck(ICmpInst *ICI, 3058fb3d57eSArtur Pilipenko SCEVExpander &Expander, 3068fb3d57eSArtur Pilipenko IRBuilder<> &Builder) { 3078fb3d57eSArtur Pilipenko DEBUG(dbgs() << "Analyzing ICmpInst condition:\n"); 3088fb3d57eSArtur Pilipenko DEBUG(ICI->dump()); 3098fb3d57eSArtur Pilipenko 310889dc1e3SArtur Pilipenko // parseLoopStructure guarantees that the latch condition is: 311b4527e1cSArtur Pilipenko // ++i <pred> latchLimit, where <pred> is u<, u<=, s<, or s<=. 312889dc1e3SArtur Pilipenko // We are looking for the range checks of the form: 313889dc1e3SArtur Pilipenko // i u< guardLimit 314a6c27804SArtur Pilipenko auto RangeCheck = parseLoopICmp(ICI); 315edee2515SArtur Pilipenko if (!RangeCheck) { 316edee2515SArtur Pilipenko DEBUG(dbgs() << "Failed to parse the loop latch condition!\n"); 3178fb3d57eSArtur Pilipenko return None; 318edee2515SArtur Pilipenko } 319889dc1e3SArtur Pilipenko if (RangeCheck->Pred != ICmpInst::ICMP_ULT) { 320889dc1e3SArtur Pilipenko DEBUG(dbgs() << "Unsupported range check predicate(" << RangeCheck->Pred 321889dc1e3SArtur Pilipenko << ")!\n"); 322889dc1e3SArtur Pilipenko return None; 323889dc1e3SArtur Pilipenko } 324889dc1e3SArtur Pilipenko auto *RangeCheckIV = RangeCheck->IV; 325889dc1e3SArtur Pilipenko auto *PostIncRangeCheckIV = RangeCheckIV->getPostIncExpr(*SE); 326889dc1e3SArtur Pilipenko if (LatchCheck.IV != PostIncRangeCheckIV) { 327889dc1e3SArtur Pilipenko DEBUG(dbgs() << "Post increment range check IV (" << *PostIncRangeCheckIV 328889dc1e3SArtur Pilipenko << ") is not the same as latch IV (" << *LatchCheck.IV 329889dc1e3SArtur Pilipenko << ")!\n"); 330889dc1e3SArtur Pilipenko return None; 331889dc1e3SArtur Pilipenko } 332889dc1e3SArtur Pilipenko assert(RangeCheckIV->getStepRecurrence(*SE)->isOne() && "must be one"); 333889dc1e3SArtur Pilipenko const SCEV *Start = RangeCheckIV->getStart(); 3348fb3d57eSArtur Pilipenko 335b4527e1cSArtur Pilipenko // Generate the widened condition: 336b4527e1cSArtur Pilipenko // i.start u< guardLimit && latchLimit <pred> guardLimit 337b4527e1cSArtur Pilipenko // where <pred> depends on the latch condition predicate. See the file 338b4527e1cSArtur Pilipenko // header comment for the reasoning. 339b4527e1cSArtur Pilipenko ICmpInst::Predicate LimitCheckPred; 340b4527e1cSArtur Pilipenko switch (LatchCheck.Pred) { 341b4527e1cSArtur Pilipenko case ICmpInst::ICMP_ULT: 342b4527e1cSArtur Pilipenko LimitCheckPred = ICmpInst::ICMP_ULE; 343b4527e1cSArtur Pilipenko break; 344b4527e1cSArtur Pilipenko case ICmpInst::ICMP_ULE: 345b4527e1cSArtur Pilipenko LimitCheckPred = ICmpInst::ICMP_ULT; 346b4527e1cSArtur Pilipenko break; 347b4527e1cSArtur Pilipenko case ICmpInst::ICMP_SLT: 348b4527e1cSArtur Pilipenko LimitCheckPred = ICmpInst::ICMP_SLE; 349b4527e1cSArtur Pilipenko break; 350b4527e1cSArtur Pilipenko case ICmpInst::ICMP_SLE: 351b4527e1cSArtur Pilipenko LimitCheckPred = ICmpInst::ICMP_SLT; 352b4527e1cSArtur Pilipenko break; 353b4527e1cSArtur Pilipenko default: 354b4527e1cSArtur Pilipenko llvm_unreachable("Unsupported loop latch!"); 355b4527e1cSArtur Pilipenko } 356aab28666SArtur Pilipenko 357aab28666SArtur Pilipenko auto CanExpand = [this](const SCEV *S) { 358aab28666SArtur Pilipenko return SE->isLoopInvariant(S, L) && isSafeToExpand(S, *SE); 359aab28666SArtur Pilipenko }; 360889dc1e3SArtur Pilipenko if (!CanExpand(Start) || !CanExpand(LatchCheck.Limit) || 361889dc1e3SArtur Pilipenko !CanExpand(RangeCheck->Limit)) 3628fb3d57eSArtur Pilipenko return None; 3638fb3d57eSArtur Pilipenko 3640860bfc6SArtur Pilipenko Instruction *InsertAt = Preheader->getTerminator(); 365889dc1e3SArtur Pilipenko auto *LimitCheck = expandCheck(Expander, Builder, LimitCheckPred, 366889dc1e3SArtur Pilipenko LatchCheck.Limit, RangeCheck->Limit, InsertAt); 367*ead69ee4SArtur Pilipenko auto *FirstIterationCheck = expandCheck(Expander, Builder, RangeCheck->Pred, 368*ead69ee4SArtur Pilipenko Start, RangeCheck->Limit, InsertAt); 369889dc1e3SArtur Pilipenko return Builder.CreateAnd(FirstIterationCheck, LimitCheck); 3708fb3d57eSArtur Pilipenko } 3718fb3d57eSArtur Pilipenko 3728fb3d57eSArtur Pilipenko bool LoopPredication::widenGuardConditions(IntrinsicInst *Guard, 3738fb3d57eSArtur Pilipenko SCEVExpander &Expander) { 3748fb3d57eSArtur Pilipenko DEBUG(dbgs() << "Processing guard:\n"); 3758fb3d57eSArtur Pilipenko DEBUG(Guard->dump()); 3768fb3d57eSArtur Pilipenko 3778fb3d57eSArtur Pilipenko IRBuilder<> Builder(cast<Instruction>(Preheader->getTerminator())); 3788fb3d57eSArtur Pilipenko 3798fb3d57eSArtur Pilipenko // The guard condition is expected to be in form of: 3808fb3d57eSArtur Pilipenko // cond1 && cond2 && cond3 ... 3818fb3d57eSArtur Pilipenko // Iterate over subconditions looking for for icmp conditions which can be 3828fb3d57eSArtur Pilipenko // widened across loop iterations. Widening these conditions remember the 3838fb3d57eSArtur Pilipenko // resulting list of subconditions in Checks vector. 3848fb3d57eSArtur Pilipenko SmallVector<Value *, 4> Worklist(1, Guard->getOperand(0)); 3858fb3d57eSArtur Pilipenko SmallPtrSet<Value *, 4> Visited; 3868fb3d57eSArtur Pilipenko 3878fb3d57eSArtur Pilipenko SmallVector<Value *, 4> Checks; 3888fb3d57eSArtur Pilipenko 3898fb3d57eSArtur Pilipenko unsigned NumWidened = 0; 3908fb3d57eSArtur Pilipenko do { 3918fb3d57eSArtur Pilipenko Value *Condition = Worklist.pop_back_val(); 3928fb3d57eSArtur Pilipenko if (!Visited.insert(Condition).second) 3938fb3d57eSArtur Pilipenko continue; 3948fb3d57eSArtur Pilipenko 3958fb3d57eSArtur Pilipenko Value *LHS, *RHS; 3968fb3d57eSArtur Pilipenko using namespace llvm::PatternMatch; 3978fb3d57eSArtur Pilipenko if (match(Condition, m_And(m_Value(LHS), m_Value(RHS)))) { 3988fb3d57eSArtur Pilipenko Worklist.push_back(LHS); 3998fb3d57eSArtur Pilipenko Worklist.push_back(RHS); 4008fb3d57eSArtur Pilipenko continue; 4018fb3d57eSArtur Pilipenko } 4028fb3d57eSArtur Pilipenko 4038fb3d57eSArtur Pilipenko if (ICmpInst *ICI = dyn_cast<ICmpInst>(Condition)) { 4048fb3d57eSArtur Pilipenko if (auto NewRangeCheck = widenICmpRangeCheck(ICI, Expander, Builder)) { 4058fb3d57eSArtur Pilipenko Checks.push_back(NewRangeCheck.getValue()); 4068fb3d57eSArtur Pilipenko NumWidened++; 4078fb3d57eSArtur Pilipenko continue; 4088fb3d57eSArtur Pilipenko } 4098fb3d57eSArtur Pilipenko } 4108fb3d57eSArtur Pilipenko 4118fb3d57eSArtur Pilipenko // Save the condition as is if we can't widen it 4128fb3d57eSArtur Pilipenko Checks.push_back(Condition); 4138fb3d57eSArtur Pilipenko } while (Worklist.size() != 0); 4148fb3d57eSArtur Pilipenko 4158fb3d57eSArtur Pilipenko if (NumWidened == 0) 4168fb3d57eSArtur Pilipenko return false; 4178fb3d57eSArtur Pilipenko 4188fb3d57eSArtur Pilipenko // Emit the new guard condition 4198fb3d57eSArtur Pilipenko Builder.SetInsertPoint(Guard); 4208fb3d57eSArtur Pilipenko Value *LastCheck = nullptr; 4218fb3d57eSArtur Pilipenko for (auto *Check : Checks) 4228fb3d57eSArtur Pilipenko if (!LastCheck) 4238fb3d57eSArtur Pilipenko LastCheck = Check; 4248fb3d57eSArtur Pilipenko else 4258fb3d57eSArtur Pilipenko LastCheck = Builder.CreateAnd(LastCheck, Check); 4268fb3d57eSArtur Pilipenko Guard->setOperand(0, LastCheck); 4278fb3d57eSArtur Pilipenko 4288fb3d57eSArtur Pilipenko DEBUG(dbgs() << "Widened checks = " << NumWidened << "\n"); 4298fb3d57eSArtur Pilipenko return true; 4308fb3d57eSArtur Pilipenko } 4318fb3d57eSArtur Pilipenko 432889dc1e3SArtur Pilipenko Optional<LoopPredication::LoopICmp> LoopPredication::parseLoopLatchICmp() { 433889dc1e3SArtur Pilipenko using namespace PatternMatch; 434889dc1e3SArtur Pilipenko 435889dc1e3SArtur Pilipenko BasicBlock *LoopLatch = L->getLoopLatch(); 436889dc1e3SArtur Pilipenko if (!LoopLatch) { 437889dc1e3SArtur Pilipenko DEBUG(dbgs() << "The loop doesn't have a single latch!\n"); 438889dc1e3SArtur Pilipenko return None; 439889dc1e3SArtur Pilipenko } 440889dc1e3SArtur Pilipenko 441889dc1e3SArtur Pilipenko ICmpInst::Predicate Pred; 442889dc1e3SArtur Pilipenko Value *LHS, *RHS; 443889dc1e3SArtur Pilipenko BasicBlock *TrueDest, *FalseDest; 444889dc1e3SArtur Pilipenko 445889dc1e3SArtur Pilipenko if (!match(LoopLatch->getTerminator(), 446889dc1e3SArtur Pilipenko m_Br(m_ICmp(Pred, m_Value(LHS), m_Value(RHS)), TrueDest, 447889dc1e3SArtur Pilipenko FalseDest))) { 448889dc1e3SArtur Pilipenko DEBUG(dbgs() << "Failed to match the latch terminator!\n"); 449889dc1e3SArtur Pilipenko return None; 450889dc1e3SArtur Pilipenko } 451889dc1e3SArtur Pilipenko assert((TrueDest == L->getHeader() || FalseDest == L->getHeader()) && 452889dc1e3SArtur Pilipenko "One of the latch's destinations must be the header"); 453889dc1e3SArtur Pilipenko if (TrueDest != L->getHeader()) 454889dc1e3SArtur Pilipenko Pred = ICmpInst::getInversePredicate(Pred); 455889dc1e3SArtur Pilipenko 456889dc1e3SArtur Pilipenko auto Result = parseLoopICmp(Pred, LHS, RHS); 457889dc1e3SArtur Pilipenko if (!Result) { 458889dc1e3SArtur Pilipenko DEBUG(dbgs() << "Failed to parse the loop latch condition!\n"); 459889dc1e3SArtur Pilipenko return None; 460889dc1e3SArtur Pilipenko } 461889dc1e3SArtur Pilipenko 462889dc1e3SArtur Pilipenko if (Result->Pred != ICmpInst::ICMP_ULT && 463b4527e1cSArtur Pilipenko Result->Pred != ICmpInst::ICMP_SLT && 464b4527e1cSArtur Pilipenko Result->Pred != ICmpInst::ICMP_ULE && 465b4527e1cSArtur Pilipenko Result->Pred != ICmpInst::ICMP_SLE) { 466889dc1e3SArtur Pilipenko DEBUG(dbgs() << "Unsupported loop latch predicate(" << Result->Pred 467889dc1e3SArtur Pilipenko << ")!\n"); 468889dc1e3SArtur Pilipenko return None; 469889dc1e3SArtur Pilipenko } 470889dc1e3SArtur Pilipenko 471889dc1e3SArtur Pilipenko // Check affine first, so if it's not we don't try to compute the step 472889dc1e3SArtur Pilipenko // recurrence. 473889dc1e3SArtur Pilipenko if (!Result->IV->isAffine()) { 474889dc1e3SArtur Pilipenko DEBUG(dbgs() << "The induction variable is not affine!\n"); 475889dc1e3SArtur Pilipenko return None; 476889dc1e3SArtur Pilipenko } 477889dc1e3SArtur Pilipenko 478889dc1e3SArtur Pilipenko auto *Step = Result->IV->getStepRecurrence(*SE); 479889dc1e3SArtur Pilipenko if (!Step->isOne()) { 480889dc1e3SArtur Pilipenko DEBUG(dbgs() << "Unsupported loop stride(" << *Step << ")!\n"); 481889dc1e3SArtur Pilipenko return None; 482889dc1e3SArtur Pilipenko } 483889dc1e3SArtur Pilipenko 484889dc1e3SArtur Pilipenko return Result; 485889dc1e3SArtur Pilipenko } 486889dc1e3SArtur Pilipenko 4878fb3d57eSArtur Pilipenko bool LoopPredication::runOnLoop(Loop *Loop) { 4888fb3d57eSArtur Pilipenko L = Loop; 4898fb3d57eSArtur Pilipenko 4908fb3d57eSArtur Pilipenko DEBUG(dbgs() << "Analyzing "); 4918fb3d57eSArtur Pilipenko DEBUG(L->dump()); 4928fb3d57eSArtur Pilipenko 4938fb3d57eSArtur Pilipenko Module *M = L->getHeader()->getModule(); 4948fb3d57eSArtur Pilipenko 4958fb3d57eSArtur Pilipenko // There is nothing to do if the module doesn't use guards 4968fb3d57eSArtur Pilipenko auto *GuardDecl = 4978fb3d57eSArtur Pilipenko M->getFunction(Intrinsic::getName(Intrinsic::experimental_guard)); 4988fb3d57eSArtur Pilipenko if (!GuardDecl || GuardDecl->use_empty()) 4998fb3d57eSArtur Pilipenko return false; 5008fb3d57eSArtur Pilipenko 5018fb3d57eSArtur Pilipenko DL = &M->getDataLayout(); 5028fb3d57eSArtur Pilipenko 5038fb3d57eSArtur Pilipenko Preheader = L->getLoopPreheader(); 5048fb3d57eSArtur Pilipenko if (!Preheader) 5058fb3d57eSArtur Pilipenko return false; 5068fb3d57eSArtur Pilipenko 507889dc1e3SArtur Pilipenko auto LatchCheckOpt = parseLoopLatchICmp(); 508889dc1e3SArtur Pilipenko if (!LatchCheckOpt) 509889dc1e3SArtur Pilipenko return false; 510889dc1e3SArtur Pilipenko LatchCheck = *LatchCheckOpt; 511889dc1e3SArtur Pilipenko 5128fb3d57eSArtur Pilipenko // Collect all the guards into a vector and process later, so as not 5138fb3d57eSArtur Pilipenko // to invalidate the instruction iterator. 5148fb3d57eSArtur Pilipenko SmallVector<IntrinsicInst *, 4> Guards; 5158fb3d57eSArtur Pilipenko for (const auto BB : L->blocks()) 5168fb3d57eSArtur Pilipenko for (auto &I : *BB) 5178fb3d57eSArtur Pilipenko if (auto *II = dyn_cast<IntrinsicInst>(&I)) 5188fb3d57eSArtur Pilipenko if (II->getIntrinsicID() == Intrinsic::experimental_guard) 5198fb3d57eSArtur Pilipenko Guards.push_back(II); 5208fb3d57eSArtur Pilipenko 52146c4e0a4SArtur Pilipenko if (Guards.empty()) 52246c4e0a4SArtur Pilipenko return false; 52346c4e0a4SArtur Pilipenko 5248fb3d57eSArtur Pilipenko SCEVExpander Expander(*SE, *DL, "loop-predication"); 5258fb3d57eSArtur Pilipenko 5268fb3d57eSArtur Pilipenko bool Changed = false; 5278fb3d57eSArtur Pilipenko for (auto *Guard : Guards) 5288fb3d57eSArtur Pilipenko Changed |= widenGuardConditions(Guard, Expander); 5298fb3d57eSArtur Pilipenko 5308fb3d57eSArtur Pilipenko return Changed; 5318fb3d57eSArtur Pilipenko } 532