1483e9246SAleksandr Popov #include "llvm/Transforms/Utils/LoopConstrainer.h" 2483e9246SAleksandr Popov #include "llvm/Analysis/LoopInfo.h" 3483e9246SAleksandr Popov #include "llvm/Analysis/ScalarEvolution.h" 4483e9246SAleksandr Popov #include "llvm/Analysis/ScalarEvolutionExpressions.h" 5483e9246SAleksandr Popov #include "llvm/IR/Dominators.h" 6483e9246SAleksandr Popov #include "llvm/Transforms/Utils/Cloning.h" 7483e9246SAleksandr Popov #include "llvm/Transforms/Utils/LoopSimplify.h" 8483e9246SAleksandr Popov #include "llvm/Transforms/Utils/LoopUtils.h" 9483e9246SAleksandr Popov #include "llvm/Transforms/Utils/ScalarEvolutionExpander.h" 10483e9246SAleksandr Popov 11483e9246SAleksandr Popov using namespace llvm; 12483e9246SAleksandr Popov 13483e9246SAleksandr Popov static const char *ClonedLoopTag = "loop_constrainer.loop.clone"; 14483e9246SAleksandr Popov 15483e9246SAleksandr Popov #define DEBUG_TYPE "loop-constrainer" 16483e9246SAleksandr Popov 17483e9246SAleksandr Popov /// Given a loop with an deccreasing induction variable, is it possible to 18483e9246SAleksandr Popov /// safely calculate the bounds of a new loop using the given Predicate. 19483e9246SAleksandr Popov static bool isSafeDecreasingBound(const SCEV *Start, const SCEV *BoundSCEV, 20483e9246SAleksandr Popov const SCEV *Step, ICmpInst::Predicate Pred, 21483e9246SAleksandr Popov unsigned LatchBrExitIdx, Loop *L, 22483e9246SAleksandr Popov ScalarEvolution &SE) { 23483e9246SAleksandr Popov if (Pred != ICmpInst::ICMP_SLT && Pred != ICmpInst::ICMP_SGT && 24483e9246SAleksandr Popov Pred != ICmpInst::ICMP_ULT && Pred != ICmpInst::ICMP_UGT) 25483e9246SAleksandr Popov return false; 26483e9246SAleksandr Popov 27483e9246SAleksandr Popov if (!SE.isAvailableAtLoopEntry(BoundSCEV, L)) 28483e9246SAleksandr Popov return false; 29483e9246SAleksandr Popov 30483e9246SAleksandr Popov assert(SE.isKnownNegative(Step) && "expecting negative step"); 31483e9246SAleksandr Popov 32483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "isSafeDecreasingBound with:\n"); 33483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "Start: " << *Start << "\n"); 34483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "Step: " << *Step << "\n"); 35483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "BoundSCEV: " << *BoundSCEV << "\n"); 36483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "Pred: " << Pred << "\n"); 37483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "LatchExitBrIdx: " << LatchBrExitIdx << "\n"); 38483e9246SAleksandr Popov 39483e9246SAleksandr Popov bool IsSigned = ICmpInst::isSigned(Pred); 40483e9246SAleksandr Popov // The predicate that we need to check that the induction variable lies 41483e9246SAleksandr Popov // within bounds. 42483e9246SAleksandr Popov ICmpInst::Predicate BoundPred = 43483e9246SAleksandr Popov IsSigned ? CmpInst::ICMP_SGT : CmpInst::ICMP_UGT; 44483e9246SAleksandr Popov 45cd206007SAleksandr Popov auto StartLG = SE.applyLoopGuards(Start, L); 46cd206007SAleksandr Popov auto BoundLG = SE.applyLoopGuards(BoundSCEV, L); 47cd206007SAleksandr Popov 48483e9246SAleksandr Popov if (LatchBrExitIdx == 1) 49cd206007SAleksandr Popov return SE.isLoopEntryGuardedByCond(L, BoundPred, StartLG, BoundLG); 50483e9246SAleksandr Popov 51483e9246SAleksandr Popov assert(LatchBrExitIdx == 0 && "LatchBrExitIdx should be either 0 or 1"); 52483e9246SAleksandr Popov 53483e9246SAleksandr Popov const SCEV *StepPlusOne = SE.getAddExpr(Step, SE.getOne(Step->getType())); 54483e9246SAleksandr Popov unsigned BitWidth = cast<IntegerType>(BoundSCEV->getType())->getBitWidth(); 55483e9246SAleksandr Popov APInt Min = IsSigned ? APInt::getSignedMinValue(BitWidth) 56483e9246SAleksandr Popov : APInt::getMinValue(BitWidth); 57483e9246SAleksandr Popov const SCEV *Limit = SE.getMinusSCEV(SE.getConstant(Min), StepPlusOne); 58483e9246SAleksandr Popov 59483e9246SAleksandr Popov const SCEV *MinusOne = 60cd206007SAleksandr Popov SE.getMinusSCEV(BoundLG, SE.getOne(BoundLG->getType())); 61483e9246SAleksandr Popov 62cd206007SAleksandr Popov return SE.isLoopEntryGuardedByCond(L, BoundPred, StartLG, MinusOne) && 63cd206007SAleksandr Popov SE.isLoopEntryGuardedByCond(L, BoundPred, BoundLG, Limit); 64483e9246SAleksandr Popov } 65483e9246SAleksandr Popov 66483e9246SAleksandr Popov /// Given a loop with an increasing induction variable, is it possible to 67483e9246SAleksandr Popov /// safely calculate the bounds of a new loop using the given Predicate. 68483e9246SAleksandr Popov static bool isSafeIncreasingBound(const SCEV *Start, const SCEV *BoundSCEV, 69483e9246SAleksandr Popov const SCEV *Step, ICmpInst::Predicate Pred, 70483e9246SAleksandr Popov unsigned LatchBrExitIdx, Loop *L, 71483e9246SAleksandr Popov ScalarEvolution &SE) { 72483e9246SAleksandr Popov if (Pred != ICmpInst::ICMP_SLT && Pred != ICmpInst::ICMP_SGT && 73483e9246SAleksandr Popov Pred != ICmpInst::ICMP_ULT && Pred != ICmpInst::ICMP_UGT) 74483e9246SAleksandr Popov return false; 75483e9246SAleksandr Popov 76483e9246SAleksandr Popov if (!SE.isAvailableAtLoopEntry(BoundSCEV, L)) 77483e9246SAleksandr Popov return false; 78483e9246SAleksandr Popov 79483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "isSafeIncreasingBound with:\n"); 80483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "Start: " << *Start << "\n"); 81483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "Step: " << *Step << "\n"); 82483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "BoundSCEV: " << *BoundSCEV << "\n"); 83483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "Pred: " << Pred << "\n"); 84483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "LatchExitBrIdx: " << LatchBrExitIdx << "\n"); 85483e9246SAleksandr Popov 86483e9246SAleksandr Popov bool IsSigned = ICmpInst::isSigned(Pred); 87483e9246SAleksandr Popov // The predicate that we need to check that the induction variable lies 88483e9246SAleksandr Popov // within bounds. 89483e9246SAleksandr Popov ICmpInst::Predicate BoundPred = 90483e9246SAleksandr Popov IsSigned ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT; 91483e9246SAleksandr Popov 92cd206007SAleksandr Popov auto StartLG = SE.applyLoopGuards(Start, L); 93cd206007SAleksandr Popov auto BoundLG = SE.applyLoopGuards(BoundSCEV, L); 94cd206007SAleksandr Popov 95483e9246SAleksandr Popov if (LatchBrExitIdx == 1) 96cd206007SAleksandr Popov return SE.isLoopEntryGuardedByCond(L, BoundPred, StartLG, BoundLG); 97483e9246SAleksandr Popov 98483e9246SAleksandr Popov assert(LatchBrExitIdx == 0 && "LatchBrExitIdx should be 0 or 1"); 99483e9246SAleksandr Popov 100483e9246SAleksandr Popov const SCEV *StepMinusOne = SE.getMinusSCEV(Step, SE.getOne(Step->getType())); 101483e9246SAleksandr Popov unsigned BitWidth = cast<IntegerType>(BoundSCEV->getType())->getBitWidth(); 102483e9246SAleksandr Popov APInt Max = IsSigned ? APInt::getSignedMaxValue(BitWidth) 103483e9246SAleksandr Popov : APInt::getMaxValue(BitWidth); 104483e9246SAleksandr Popov const SCEV *Limit = SE.getMinusSCEV(SE.getConstant(Max), StepMinusOne); 105483e9246SAleksandr Popov 106cd206007SAleksandr Popov return (SE.isLoopEntryGuardedByCond(L, BoundPred, StartLG, 107cd206007SAleksandr Popov SE.getAddExpr(BoundLG, Step)) && 108cd206007SAleksandr Popov SE.isLoopEntryGuardedByCond(L, BoundPred, BoundLG, Limit)); 109483e9246SAleksandr Popov } 110483e9246SAleksandr Popov 111483e9246SAleksandr Popov /// Returns estimate for max latch taken count of the loop of the narrowest 112483e9246SAleksandr Popov /// available type. If the latch block has such estimate, it is returned. 113483e9246SAleksandr Popov /// Otherwise, we use max exit count of whole loop (that is potentially of wider 114483e9246SAleksandr Popov /// type than latch check itself), which is still better than no estimate. 115483e9246SAleksandr Popov static const SCEV *getNarrowestLatchMaxTakenCountEstimate(ScalarEvolution &SE, 116483e9246SAleksandr Popov const Loop &L) { 117483e9246SAleksandr Popov const SCEV *FromBlock = 118483e9246SAleksandr Popov SE.getExitCount(&L, L.getLoopLatch(), ScalarEvolution::SymbolicMaximum); 119483e9246SAleksandr Popov if (isa<SCEVCouldNotCompute>(FromBlock)) 120483e9246SAleksandr Popov return SE.getSymbolicMaxBackedgeTakenCount(&L); 121483e9246SAleksandr Popov return FromBlock; 122483e9246SAleksandr Popov } 123483e9246SAleksandr Popov 124483e9246SAleksandr Popov std::optional<LoopStructure> 125483e9246SAleksandr Popov LoopStructure::parseLoopStructure(ScalarEvolution &SE, Loop &L, 126483e9246SAleksandr Popov bool AllowUnsignedLatchCond, 127483e9246SAleksandr Popov const char *&FailureReason) { 128483e9246SAleksandr Popov if (!L.isLoopSimplifyForm()) { 129483e9246SAleksandr Popov FailureReason = "loop not in LoopSimplify form"; 130483e9246SAleksandr Popov return std::nullopt; 131483e9246SAleksandr Popov } 132483e9246SAleksandr Popov 133483e9246SAleksandr Popov BasicBlock *Latch = L.getLoopLatch(); 134483e9246SAleksandr Popov assert(Latch && "Simplified loops only have one latch!"); 135483e9246SAleksandr Popov 136483e9246SAleksandr Popov if (Latch->getTerminator()->getMetadata(ClonedLoopTag)) { 137483e9246SAleksandr Popov FailureReason = "loop has already been cloned"; 138483e9246SAleksandr Popov return std::nullopt; 139483e9246SAleksandr Popov } 140483e9246SAleksandr Popov 141483e9246SAleksandr Popov if (!L.isLoopExiting(Latch)) { 142483e9246SAleksandr Popov FailureReason = "no loop latch"; 143483e9246SAleksandr Popov return std::nullopt; 144483e9246SAleksandr Popov } 145483e9246SAleksandr Popov 146483e9246SAleksandr Popov BasicBlock *Header = L.getHeader(); 147483e9246SAleksandr Popov BasicBlock *Preheader = L.getLoopPreheader(); 148483e9246SAleksandr Popov if (!Preheader) { 149483e9246SAleksandr Popov FailureReason = "no preheader"; 150483e9246SAleksandr Popov return std::nullopt; 151483e9246SAleksandr Popov } 152483e9246SAleksandr Popov 153483e9246SAleksandr Popov BranchInst *LatchBr = dyn_cast<BranchInst>(Latch->getTerminator()); 154483e9246SAleksandr Popov if (!LatchBr || LatchBr->isUnconditional()) { 155483e9246SAleksandr Popov FailureReason = "latch terminator not conditional branch"; 156483e9246SAleksandr Popov return std::nullopt; 157483e9246SAleksandr Popov } 158483e9246SAleksandr Popov 159483e9246SAleksandr Popov unsigned LatchBrExitIdx = LatchBr->getSuccessor(0) == Header ? 1 : 0; 160483e9246SAleksandr Popov 161483e9246SAleksandr Popov ICmpInst *ICI = dyn_cast<ICmpInst>(LatchBr->getCondition()); 162483e9246SAleksandr Popov if (!ICI || !isa<IntegerType>(ICI->getOperand(0)->getType())) { 163483e9246SAleksandr Popov FailureReason = "latch terminator branch not conditional on integral icmp"; 164483e9246SAleksandr Popov return std::nullopt; 165483e9246SAleksandr Popov } 166483e9246SAleksandr Popov 167483e9246SAleksandr Popov const SCEV *MaxBETakenCount = getNarrowestLatchMaxTakenCountEstimate(SE, L); 168483e9246SAleksandr Popov if (isa<SCEVCouldNotCompute>(MaxBETakenCount)) { 169483e9246SAleksandr Popov FailureReason = "could not compute latch count"; 170483e9246SAleksandr Popov return std::nullopt; 171483e9246SAleksandr Popov } 172483e9246SAleksandr Popov assert(SE.getLoopDisposition(MaxBETakenCount, &L) == 173483e9246SAleksandr Popov ScalarEvolution::LoopInvariant && 174483e9246SAleksandr Popov "loop variant exit count doesn't make sense!"); 175483e9246SAleksandr Popov 176483e9246SAleksandr Popov ICmpInst::Predicate Pred = ICI->getPredicate(); 177483e9246SAleksandr Popov Value *LeftValue = ICI->getOperand(0); 178483e9246SAleksandr Popov const SCEV *LeftSCEV = SE.getSCEV(LeftValue); 179483e9246SAleksandr Popov IntegerType *IndVarTy = cast<IntegerType>(LeftValue->getType()); 180483e9246SAleksandr Popov 181483e9246SAleksandr Popov Value *RightValue = ICI->getOperand(1); 182483e9246SAleksandr Popov const SCEV *RightSCEV = SE.getSCEV(RightValue); 183483e9246SAleksandr Popov 184483e9246SAleksandr Popov // We canonicalize `ICI` such that `LeftSCEV` is an add recurrence. 185483e9246SAleksandr Popov if (!isa<SCEVAddRecExpr>(LeftSCEV)) { 186483e9246SAleksandr Popov if (isa<SCEVAddRecExpr>(RightSCEV)) { 187483e9246SAleksandr Popov std::swap(LeftSCEV, RightSCEV); 188483e9246SAleksandr Popov std::swap(LeftValue, RightValue); 189483e9246SAleksandr Popov Pred = ICmpInst::getSwappedPredicate(Pred); 190483e9246SAleksandr Popov } else { 191483e9246SAleksandr Popov FailureReason = "no add recurrences in the icmp"; 192483e9246SAleksandr Popov return std::nullopt; 193483e9246SAleksandr Popov } 194483e9246SAleksandr Popov } 195483e9246SAleksandr Popov 196483e9246SAleksandr Popov auto HasNoSignedWrap = [&](const SCEVAddRecExpr *AR) { 197483e9246SAleksandr Popov if (AR->getNoWrapFlags(SCEV::FlagNSW)) 198483e9246SAleksandr Popov return true; 199483e9246SAleksandr Popov 200483e9246SAleksandr Popov IntegerType *Ty = cast<IntegerType>(AR->getType()); 201483e9246SAleksandr Popov IntegerType *WideTy = 202483e9246SAleksandr Popov IntegerType::get(Ty->getContext(), Ty->getBitWidth() * 2); 203483e9246SAleksandr Popov 204483e9246SAleksandr Popov const SCEVAddRecExpr *ExtendAfterOp = 205483e9246SAleksandr Popov dyn_cast<SCEVAddRecExpr>(SE.getSignExtendExpr(AR, WideTy)); 206483e9246SAleksandr Popov if (ExtendAfterOp) { 207483e9246SAleksandr Popov const SCEV *ExtendedStart = SE.getSignExtendExpr(AR->getStart(), WideTy); 208483e9246SAleksandr Popov const SCEV *ExtendedStep = 209483e9246SAleksandr Popov SE.getSignExtendExpr(AR->getStepRecurrence(SE), WideTy); 210483e9246SAleksandr Popov 211483e9246SAleksandr Popov bool NoSignedWrap = ExtendAfterOp->getStart() == ExtendedStart && 212483e9246SAleksandr Popov ExtendAfterOp->getStepRecurrence(SE) == ExtendedStep; 213483e9246SAleksandr Popov 214483e9246SAleksandr Popov if (NoSignedWrap) 215483e9246SAleksandr Popov return true; 216483e9246SAleksandr Popov } 217483e9246SAleksandr Popov 218483e9246SAleksandr Popov // We may have proved this when computing the sign extension above. 219483e9246SAleksandr Popov return AR->getNoWrapFlags(SCEV::FlagNSW) != SCEV::FlagAnyWrap; 220483e9246SAleksandr Popov }; 221483e9246SAleksandr Popov 222483e9246SAleksandr Popov // `ICI` is interpreted as taking the backedge if the *next* value of the 223483e9246SAleksandr Popov // induction variable satisfies some constraint. 224483e9246SAleksandr Popov 225483e9246SAleksandr Popov const SCEVAddRecExpr *IndVarBase = cast<SCEVAddRecExpr>(LeftSCEV); 226483e9246SAleksandr Popov if (IndVarBase->getLoop() != &L) { 227483e9246SAleksandr Popov FailureReason = "LHS in cmp is not an AddRec for this loop"; 228483e9246SAleksandr Popov return std::nullopt; 229483e9246SAleksandr Popov } 230483e9246SAleksandr Popov if (!IndVarBase->isAffine()) { 231483e9246SAleksandr Popov FailureReason = "LHS in icmp not induction variable"; 232483e9246SAleksandr Popov return std::nullopt; 233483e9246SAleksandr Popov } 234483e9246SAleksandr Popov const SCEV *StepRec = IndVarBase->getStepRecurrence(SE); 235483e9246SAleksandr Popov if (!isa<SCEVConstant>(StepRec)) { 236483e9246SAleksandr Popov FailureReason = "LHS in icmp not induction variable"; 237483e9246SAleksandr Popov return std::nullopt; 238483e9246SAleksandr Popov } 239483e9246SAleksandr Popov ConstantInt *StepCI = cast<SCEVConstant>(StepRec)->getValue(); 240483e9246SAleksandr Popov 241483e9246SAleksandr Popov if (ICI->isEquality() && !HasNoSignedWrap(IndVarBase)) { 242483e9246SAleksandr Popov FailureReason = "LHS in icmp needs nsw for equality predicates"; 243483e9246SAleksandr Popov return std::nullopt; 244483e9246SAleksandr Popov } 245483e9246SAleksandr Popov 246483e9246SAleksandr Popov assert(!StepCI->isZero() && "Zero step?"); 247483e9246SAleksandr Popov bool IsIncreasing = !StepCI->isNegative(); 248483e9246SAleksandr Popov bool IsSignedPredicate; 249483e9246SAleksandr Popov const SCEV *StartNext = IndVarBase->getStart(); 250483e9246SAleksandr Popov const SCEV *Addend = SE.getNegativeSCEV(IndVarBase->getStepRecurrence(SE)); 251483e9246SAleksandr Popov const SCEV *IndVarStart = SE.getAddExpr(StartNext, Addend); 252483e9246SAleksandr Popov const SCEV *Step = SE.getSCEV(StepCI); 253483e9246SAleksandr Popov 254483e9246SAleksandr Popov const SCEV *FixedRightSCEV = nullptr; 255483e9246SAleksandr Popov 256483e9246SAleksandr Popov // If RightValue resides within loop (but still being loop invariant), 257483e9246SAleksandr Popov // regenerate it as preheader. 258483e9246SAleksandr Popov if (auto *I = dyn_cast<Instruction>(RightValue)) 259483e9246SAleksandr Popov if (L.contains(I->getParent())) 260483e9246SAleksandr Popov FixedRightSCEV = RightSCEV; 261483e9246SAleksandr Popov 262483e9246SAleksandr Popov if (IsIncreasing) { 263483e9246SAleksandr Popov bool DecreasedRightValueByOne = false; 264483e9246SAleksandr Popov if (StepCI->isOne()) { 265483e9246SAleksandr Popov // Try to turn eq/ne predicates to those we can work with. 266483e9246SAleksandr Popov if (Pred == ICmpInst::ICMP_NE && LatchBrExitIdx == 1) 267483e9246SAleksandr Popov // while (++i != len) { while (++i < len) { 268483e9246SAleksandr Popov // ... ---> ... 269483e9246SAleksandr Popov // } } 270483e9246SAleksandr Popov // If both parts are known non-negative, it is profitable to use 271483e9246SAleksandr Popov // unsigned comparison in increasing loop. This allows us to make the 272483e9246SAleksandr Popov // comparison check against "RightSCEV + 1" more optimistic. 273483e9246SAleksandr Popov if (isKnownNonNegativeInLoop(IndVarStart, &L, SE) && 274483e9246SAleksandr Popov isKnownNonNegativeInLoop(RightSCEV, &L, SE)) 275483e9246SAleksandr Popov Pred = ICmpInst::ICMP_ULT; 276483e9246SAleksandr Popov else 277483e9246SAleksandr Popov Pred = ICmpInst::ICMP_SLT; 278483e9246SAleksandr Popov else if (Pred == ICmpInst::ICMP_EQ && LatchBrExitIdx == 0) { 279483e9246SAleksandr Popov // while (true) { while (true) { 280483e9246SAleksandr Popov // if (++i == len) ---> if (++i > len - 1) 281483e9246SAleksandr Popov // break; break; 282483e9246SAleksandr Popov // ... ... 283483e9246SAleksandr Popov // } } 284483e9246SAleksandr Popov if (IndVarBase->getNoWrapFlags(SCEV::FlagNUW) && 285483e9246SAleksandr Popov cannotBeMinInLoop(RightSCEV, &L, SE, /*Signed*/ false)) { 286483e9246SAleksandr Popov Pred = ICmpInst::ICMP_UGT; 287483e9246SAleksandr Popov RightSCEV = 288483e9246SAleksandr Popov SE.getMinusSCEV(RightSCEV, SE.getOne(RightSCEV->getType())); 289483e9246SAleksandr Popov DecreasedRightValueByOne = true; 290483e9246SAleksandr Popov } else if (cannotBeMinInLoop(RightSCEV, &L, SE, /*Signed*/ true)) { 291483e9246SAleksandr Popov Pred = ICmpInst::ICMP_SGT; 292483e9246SAleksandr Popov RightSCEV = 293483e9246SAleksandr Popov SE.getMinusSCEV(RightSCEV, SE.getOne(RightSCEV->getType())); 294483e9246SAleksandr Popov DecreasedRightValueByOne = true; 295483e9246SAleksandr Popov } 296483e9246SAleksandr Popov } 297483e9246SAleksandr Popov } 298483e9246SAleksandr Popov 299483e9246SAleksandr Popov bool LTPred = (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_ULT); 300483e9246SAleksandr Popov bool GTPred = (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_UGT); 301483e9246SAleksandr Popov bool FoundExpectedPred = 302483e9246SAleksandr Popov (LTPred && LatchBrExitIdx == 1) || (GTPred && LatchBrExitIdx == 0); 303483e9246SAleksandr Popov 304483e9246SAleksandr Popov if (!FoundExpectedPred) { 305483e9246SAleksandr Popov FailureReason = "expected icmp slt semantically, found something else"; 306483e9246SAleksandr Popov return std::nullopt; 307483e9246SAleksandr Popov } 308483e9246SAleksandr Popov 309483e9246SAleksandr Popov IsSignedPredicate = ICmpInst::isSigned(Pred); 310483e9246SAleksandr Popov if (!IsSignedPredicate && !AllowUnsignedLatchCond) { 311483e9246SAleksandr Popov FailureReason = "unsigned latch conditions are explicitly prohibited"; 312483e9246SAleksandr Popov return std::nullopt; 313483e9246SAleksandr Popov } 314483e9246SAleksandr Popov 315483e9246SAleksandr Popov if (!isSafeIncreasingBound(IndVarStart, RightSCEV, Step, Pred, 316483e9246SAleksandr Popov LatchBrExitIdx, &L, SE)) { 317483e9246SAleksandr Popov FailureReason = "Unsafe loop bounds"; 318483e9246SAleksandr Popov return std::nullopt; 319483e9246SAleksandr Popov } 320483e9246SAleksandr Popov if (LatchBrExitIdx == 0) { 321483e9246SAleksandr Popov // We need to increase the right value unless we have already decreased 322483e9246SAleksandr Popov // it virtually when we replaced EQ with SGT. 323483e9246SAleksandr Popov if (!DecreasedRightValueByOne) 324483e9246SAleksandr Popov FixedRightSCEV = 325483e9246SAleksandr Popov SE.getAddExpr(RightSCEV, SE.getOne(RightSCEV->getType())); 326483e9246SAleksandr Popov } else { 327483e9246SAleksandr Popov assert(!DecreasedRightValueByOne && 328483e9246SAleksandr Popov "Right value can be decreased only for LatchBrExitIdx == 0!"); 329483e9246SAleksandr Popov } 330483e9246SAleksandr Popov } else { 331483e9246SAleksandr Popov bool IncreasedRightValueByOne = false; 332483e9246SAleksandr Popov if (StepCI->isMinusOne()) { 333483e9246SAleksandr Popov // Try to turn eq/ne predicates to those we can work with. 334483e9246SAleksandr Popov if (Pred == ICmpInst::ICMP_NE && LatchBrExitIdx == 1) 335483e9246SAleksandr Popov // while (--i != len) { while (--i > len) { 336483e9246SAleksandr Popov // ... ---> ... 337483e9246SAleksandr Popov // } } 338483e9246SAleksandr Popov // We intentionally don't turn the predicate into UGT even if we know 339483e9246SAleksandr Popov // that both operands are non-negative, because it will only pessimize 340483e9246SAleksandr Popov // our check against "RightSCEV - 1". 341483e9246SAleksandr Popov Pred = ICmpInst::ICMP_SGT; 342483e9246SAleksandr Popov else if (Pred == ICmpInst::ICMP_EQ && LatchBrExitIdx == 0) { 343483e9246SAleksandr Popov // while (true) { while (true) { 344483e9246SAleksandr Popov // if (--i == len) ---> if (--i < len + 1) 345483e9246SAleksandr Popov // break; break; 346483e9246SAleksandr Popov // ... ... 347483e9246SAleksandr Popov // } } 348483e9246SAleksandr Popov if (IndVarBase->getNoWrapFlags(SCEV::FlagNUW) && 349483e9246SAleksandr Popov cannotBeMaxInLoop(RightSCEV, &L, SE, /* Signed */ false)) { 350483e9246SAleksandr Popov Pred = ICmpInst::ICMP_ULT; 351483e9246SAleksandr Popov RightSCEV = SE.getAddExpr(RightSCEV, SE.getOne(RightSCEV->getType())); 352483e9246SAleksandr Popov IncreasedRightValueByOne = true; 353483e9246SAleksandr Popov } else if (cannotBeMaxInLoop(RightSCEV, &L, SE, /* Signed */ true)) { 354483e9246SAleksandr Popov Pred = ICmpInst::ICMP_SLT; 355483e9246SAleksandr Popov RightSCEV = SE.getAddExpr(RightSCEV, SE.getOne(RightSCEV->getType())); 356483e9246SAleksandr Popov IncreasedRightValueByOne = true; 357483e9246SAleksandr Popov } 358483e9246SAleksandr Popov } 359483e9246SAleksandr Popov } 360483e9246SAleksandr Popov 361483e9246SAleksandr Popov bool LTPred = (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_ULT); 362483e9246SAleksandr Popov bool GTPred = (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_UGT); 363483e9246SAleksandr Popov 364483e9246SAleksandr Popov bool FoundExpectedPred = 365483e9246SAleksandr Popov (GTPred && LatchBrExitIdx == 1) || (LTPred && LatchBrExitIdx == 0); 366483e9246SAleksandr Popov 367483e9246SAleksandr Popov if (!FoundExpectedPred) { 368483e9246SAleksandr Popov FailureReason = "expected icmp sgt semantically, found something else"; 369483e9246SAleksandr Popov return std::nullopt; 370483e9246SAleksandr Popov } 371483e9246SAleksandr Popov 372483e9246SAleksandr Popov IsSignedPredicate = 373483e9246SAleksandr Popov Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGT; 374483e9246SAleksandr Popov 375483e9246SAleksandr Popov if (!IsSignedPredicate && !AllowUnsignedLatchCond) { 376483e9246SAleksandr Popov FailureReason = "unsigned latch conditions are explicitly prohibited"; 377483e9246SAleksandr Popov return std::nullopt; 378483e9246SAleksandr Popov } 379483e9246SAleksandr Popov 380483e9246SAleksandr Popov if (!isSafeDecreasingBound(IndVarStart, RightSCEV, Step, Pred, 381483e9246SAleksandr Popov LatchBrExitIdx, &L, SE)) { 382483e9246SAleksandr Popov FailureReason = "Unsafe bounds"; 383483e9246SAleksandr Popov return std::nullopt; 384483e9246SAleksandr Popov } 385483e9246SAleksandr Popov 386483e9246SAleksandr Popov if (LatchBrExitIdx == 0) { 387483e9246SAleksandr Popov // We need to decrease the right value unless we have already increased 388483e9246SAleksandr Popov // it virtually when we replaced EQ with SLT. 389483e9246SAleksandr Popov if (!IncreasedRightValueByOne) 390483e9246SAleksandr Popov FixedRightSCEV = 391483e9246SAleksandr Popov SE.getMinusSCEV(RightSCEV, SE.getOne(RightSCEV->getType())); 392483e9246SAleksandr Popov } else { 393483e9246SAleksandr Popov assert(!IncreasedRightValueByOne && 394483e9246SAleksandr Popov "Right value can be increased only for LatchBrExitIdx == 0!"); 395483e9246SAleksandr Popov } 396483e9246SAleksandr Popov } 397483e9246SAleksandr Popov BasicBlock *LatchExit = LatchBr->getSuccessor(LatchBrExitIdx); 398483e9246SAleksandr Popov 399483e9246SAleksandr Popov assert(!L.contains(LatchExit) && "expected an exit block!"); 4002d209d96SNikita Popov const DataLayout &DL = Preheader->getDataLayout(); 401483e9246SAleksandr Popov SCEVExpander Expander(SE, DL, "loop-constrainer"); 402483e9246SAleksandr Popov Instruction *Ins = Preheader->getTerminator(); 403483e9246SAleksandr Popov 404483e9246SAleksandr Popov if (FixedRightSCEV) 405483e9246SAleksandr Popov RightValue = 406483e9246SAleksandr Popov Expander.expandCodeFor(FixedRightSCEV, FixedRightSCEV->getType(), Ins); 407483e9246SAleksandr Popov 408483e9246SAleksandr Popov Value *IndVarStartV = Expander.expandCodeFor(IndVarStart, IndVarTy, Ins); 409483e9246SAleksandr Popov IndVarStartV->setName("indvar.start"); 410483e9246SAleksandr Popov 411483e9246SAleksandr Popov LoopStructure Result; 412483e9246SAleksandr Popov 413483e9246SAleksandr Popov Result.Tag = "main"; 414483e9246SAleksandr Popov Result.Header = Header; 415483e9246SAleksandr Popov Result.Latch = Latch; 416483e9246SAleksandr Popov Result.LatchBr = LatchBr; 417483e9246SAleksandr Popov Result.LatchExit = LatchExit; 418483e9246SAleksandr Popov Result.LatchBrExitIdx = LatchBrExitIdx; 419483e9246SAleksandr Popov Result.IndVarStart = IndVarStartV; 420483e9246SAleksandr Popov Result.IndVarStep = StepCI; 421483e9246SAleksandr Popov Result.IndVarBase = LeftValue; 422483e9246SAleksandr Popov Result.IndVarIncreasing = IsIncreasing; 423483e9246SAleksandr Popov Result.LoopExitAt = RightValue; 424483e9246SAleksandr Popov Result.IsSignedPredicate = IsSignedPredicate; 425483e9246SAleksandr Popov Result.ExitCountTy = cast<IntegerType>(MaxBETakenCount->getType()); 426483e9246SAleksandr Popov 427483e9246SAleksandr Popov FailureReason = nullptr; 428483e9246SAleksandr Popov 429483e9246SAleksandr Popov return Result; 430483e9246SAleksandr Popov } 431483e9246SAleksandr Popov 432483e9246SAleksandr Popov // Add metadata to the loop L to disable loop optimizations. Callers need to 433483e9246SAleksandr Popov // confirm that optimizing loop L is not beneficial. 434483e9246SAleksandr Popov static void DisableAllLoopOptsOnLoop(Loop &L) { 435483e9246SAleksandr Popov // We do not care about any existing loopID related metadata for L, since we 436483e9246SAleksandr Popov // are setting all loop metadata to false. 437483e9246SAleksandr Popov LLVMContext &Context = L.getHeader()->getContext(); 438483e9246SAleksandr Popov // Reserve first location for self reference to the LoopID metadata node. 439483e9246SAleksandr Popov MDNode *Dummy = MDNode::get(Context, {}); 440483e9246SAleksandr Popov MDNode *DisableUnroll = MDNode::get( 441483e9246SAleksandr Popov Context, {MDString::get(Context, "llvm.loop.unroll.disable")}); 442483e9246SAleksandr Popov Metadata *FalseVal = 443483e9246SAleksandr Popov ConstantAsMetadata::get(ConstantInt::get(Type::getInt1Ty(Context), 0)); 444483e9246SAleksandr Popov MDNode *DisableVectorize = MDNode::get( 445483e9246SAleksandr Popov Context, 446483e9246SAleksandr Popov {MDString::get(Context, "llvm.loop.vectorize.enable"), FalseVal}); 447483e9246SAleksandr Popov MDNode *DisableLICMVersioning = MDNode::get( 448483e9246SAleksandr Popov Context, {MDString::get(Context, "llvm.loop.licm_versioning.disable")}); 449483e9246SAleksandr Popov MDNode *DisableDistribution = MDNode::get( 450483e9246SAleksandr Popov Context, 451483e9246SAleksandr Popov {MDString::get(Context, "llvm.loop.distribute.enable"), FalseVal}); 452483e9246SAleksandr Popov MDNode *NewLoopID = 453483e9246SAleksandr Popov MDNode::get(Context, {Dummy, DisableUnroll, DisableVectorize, 454483e9246SAleksandr Popov DisableLICMVersioning, DisableDistribution}); 455483e9246SAleksandr Popov // Set operand 0 to refer to the loop id itself. 456483e9246SAleksandr Popov NewLoopID->replaceOperandWith(0, NewLoopID); 457483e9246SAleksandr Popov L.setLoopID(NewLoopID); 458483e9246SAleksandr Popov } 459483e9246SAleksandr Popov 460483e9246SAleksandr Popov LoopConstrainer::LoopConstrainer(Loop &L, LoopInfo &LI, 461483e9246SAleksandr Popov function_ref<void(Loop *, bool)> LPMAddNewLoop, 462483e9246SAleksandr Popov const LoopStructure &LS, ScalarEvolution &SE, 463483e9246SAleksandr Popov DominatorTree &DT, Type *T, SubRanges SR) 464483e9246SAleksandr Popov : F(*L.getHeader()->getParent()), Ctx(L.getHeader()->getContext()), SE(SE), 465483e9246SAleksandr Popov DT(DT), LI(LI), LPMAddNewLoop(LPMAddNewLoop), OriginalLoop(L), RangeTy(T), 466483e9246SAleksandr Popov MainLoopStructure(LS), SR(SR) {} 467483e9246SAleksandr Popov 468483e9246SAleksandr Popov void LoopConstrainer::cloneLoop(LoopConstrainer::ClonedLoop &Result, 469483e9246SAleksandr Popov const char *Tag) const { 470483e9246SAleksandr Popov for (BasicBlock *BB : OriginalLoop.getBlocks()) { 471483e9246SAleksandr Popov BasicBlock *Clone = CloneBasicBlock(BB, Result.Map, Twine(".") + Tag, &F); 472483e9246SAleksandr Popov Result.Blocks.push_back(Clone); 473483e9246SAleksandr Popov Result.Map[BB] = Clone; 474483e9246SAleksandr Popov } 475483e9246SAleksandr Popov 476483e9246SAleksandr Popov auto GetClonedValue = [&Result](Value *V) { 477483e9246SAleksandr Popov assert(V && "null values not in domain!"); 478483e9246SAleksandr Popov auto It = Result.Map.find(V); 479483e9246SAleksandr Popov if (It == Result.Map.end()) 480483e9246SAleksandr Popov return V; 481483e9246SAleksandr Popov return static_cast<Value *>(It->second); 482483e9246SAleksandr Popov }; 483483e9246SAleksandr Popov 484483e9246SAleksandr Popov auto *ClonedLatch = 485483e9246SAleksandr Popov cast<BasicBlock>(GetClonedValue(OriginalLoop.getLoopLatch())); 486483e9246SAleksandr Popov ClonedLatch->getTerminator()->setMetadata(ClonedLoopTag, 487483e9246SAleksandr Popov MDNode::get(Ctx, {})); 488483e9246SAleksandr Popov 489483e9246SAleksandr Popov Result.Structure = MainLoopStructure.map(GetClonedValue); 490483e9246SAleksandr Popov Result.Structure.Tag = Tag; 491483e9246SAleksandr Popov 492483e9246SAleksandr Popov for (unsigned i = 0, e = Result.Blocks.size(); i != e; ++i) { 493483e9246SAleksandr Popov BasicBlock *ClonedBB = Result.Blocks[i]; 494483e9246SAleksandr Popov BasicBlock *OriginalBB = OriginalLoop.getBlocks()[i]; 495483e9246SAleksandr Popov 496483e9246SAleksandr Popov assert(Result.Map[OriginalBB] == ClonedBB && "invariant!"); 497483e9246SAleksandr Popov 498483e9246SAleksandr Popov for (Instruction &I : *ClonedBB) 499483e9246SAleksandr Popov RemapInstruction(&I, Result.Map, 500483e9246SAleksandr Popov RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); 501483e9246SAleksandr Popov 502483e9246SAleksandr Popov // Exit blocks will now have one more predecessor and their PHI nodes need 503483e9246SAleksandr Popov // to be edited to reflect that. No phi nodes need to be introduced because 504483e9246SAleksandr Popov // the loop is in LCSSA. 505483e9246SAleksandr Popov 506483e9246SAleksandr Popov for (auto *SBB : successors(OriginalBB)) { 507483e9246SAleksandr Popov if (OriginalLoop.contains(SBB)) 508483e9246SAleksandr Popov continue; // not an exit block 509483e9246SAleksandr Popov 510483e9246SAleksandr Popov for (PHINode &PN : SBB->phis()) { 511483e9246SAleksandr Popov Value *OldIncoming = PN.getIncomingValueForBlock(OriginalBB); 512483e9246SAleksandr Popov PN.addIncoming(GetClonedValue(OldIncoming), ClonedBB); 513*c8e06728SNikita Popov SE.forgetLcssaPhiWithNewPredecessor(&OriginalLoop, &PN); 514483e9246SAleksandr Popov } 515483e9246SAleksandr Popov } 516483e9246SAleksandr Popov } 517483e9246SAleksandr Popov } 518483e9246SAleksandr Popov 519483e9246SAleksandr Popov LoopConstrainer::RewrittenRangeInfo LoopConstrainer::changeIterationSpaceEnd( 520483e9246SAleksandr Popov const LoopStructure &LS, BasicBlock *Preheader, Value *ExitSubloopAt, 521483e9246SAleksandr Popov BasicBlock *ContinuationBlock) const { 522483e9246SAleksandr Popov // We start with a loop with a single latch: 523483e9246SAleksandr Popov // 524483e9246SAleksandr Popov // +--------------------+ 525483e9246SAleksandr Popov // | | 526483e9246SAleksandr Popov // | preheader | 527483e9246SAleksandr Popov // | | 528483e9246SAleksandr Popov // +--------+-----------+ 529483e9246SAleksandr Popov // | ----------------\ 530483e9246SAleksandr Popov // | / | 531483e9246SAleksandr Popov // +--------v----v------+ | 532483e9246SAleksandr Popov // | | | 533483e9246SAleksandr Popov // | header | | 534483e9246SAleksandr Popov // | | | 535483e9246SAleksandr Popov // +--------------------+ | 536483e9246SAleksandr Popov // | 537483e9246SAleksandr Popov // ..... | 538483e9246SAleksandr Popov // | 539483e9246SAleksandr Popov // +--------------------+ | 540483e9246SAleksandr Popov // | | | 541483e9246SAleksandr Popov // | latch >----------/ 542483e9246SAleksandr Popov // | | 543483e9246SAleksandr Popov // +-------v------------+ 544483e9246SAleksandr Popov // | 545483e9246SAleksandr Popov // | 546483e9246SAleksandr Popov // | +--------------------+ 547483e9246SAleksandr Popov // | | | 548483e9246SAleksandr Popov // +---> original exit | 549483e9246SAleksandr Popov // | | 550483e9246SAleksandr Popov // +--------------------+ 551483e9246SAleksandr Popov // 552483e9246SAleksandr Popov // We change the control flow to look like 553483e9246SAleksandr Popov // 554483e9246SAleksandr Popov // 555483e9246SAleksandr Popov // +--------------------+ 556483e9246SAleksandr Popov // | | 557483e9246SAleksandr Popov // | preheader >-------------------------+ 558483e9246SAleksandr Popov // | | | 559483e9246SAleksandr Popov // +--------v-----------+ | 560483e9246SAleksandr Popov // | /-------------+ | 561483e9246SAleksandr Popov // | / | | 562483e9246SAleksandr Popov // +--------v--v--------+ | | 563483e9246SAleksandr Popov // | | | | 564483e9246SAleksandr Popov // | header | | +--------+ | 565483e9246SAleksandr Popov // | | | | | | 566483e9246SAleksandr Popov // +--------------------+ | | +-----v-----v-----------+ 567483e9246SAleksandr Popov // | | | | 568483e9246SAleksandr Popov // | | | .pseudo.exit | 569483e9246SAleksandr Popov // | | | | 570483e9246SAleksandr Popov // | | +-----------v-----------+ 571483e9246SAleksandr Popov // | | | 572483e9246SAleksandr Popov // ..... | | | 573483e9246SAleksandr Popov // | | +--------v-------------+ 574483e9246SAleksandr Popov // +--------------------+ | | | | 575483e9246SAleksandr Popov // | | | | | ContinuationBlock | 576483e9246SAleksandr Popov // | latch >------+ | | | 577483e9246SAleksandr Popov // | | | +----------------------+ 578483e9246SAleksandr Popov // +---------v----------+ | 579483e9246SAleksandr Popov // | | 580483e9246SAleksandr Popov // | | 581483e9246SAleksandr Popov // | +---------------^-----+ 582483e9246SAleksandr Popov // | | | 583483e9246SAleksandr Popov // +-----> .exit.selector | 584483e9246SAleksandr Popov // | | 585483e9246SAleksandr Popov // +----------v----------+ 586483e9246SAleksandr Popov // | 587483e9246SAleksandr Popov // +--------------------+ | 588483e9246SAleksandr Popov // | | | 589483e9246SAleksandr Popov // | original exit <----+ 590483e9246SAleksandr Popov // | | 591483e9246SAleksandr Popov // +--------------------+ 592483e9246SAleksandr Popov 593483e9246SAleksandr Popov RewrittenRangeInfo RRI; 594483e9246SAleksandr Popov 595483e9246SAleksandr Popov BasicBlock *BBInsertLocation = LS.Latch->getNextNode(); 596483e9246SAleksandr Popov RRI.ExitSelector = BasicBlock::Create(Ctx, Twine(LS.Tag) + ".exit.selector", 597483e9246SAleksandr Popov &F, BBInsertLocation); 598483e9246SAleksandr Popov RRI.PseudoExit = BasicBlock::Create(Ctx, Twine(LS.Tag) + ".pseudo.exit", &F, 599483e9246SAleksandr Popov BBInsertLocation); 600483e9246SAleksandr Popov 601483e9246SAleksandr Popov BranchInst *PreheaderJump = cast<BranchInst>(Preheader->getTerminator()); 602483e9246SAleksandr Popov bool Increasing = LS.IndVarIncreasing; 603483e9246SAleksandr Popov bool IsSignedPredicate = LS.IsSignedPredicate; 604483e9246SAleksandr Popov 605483e9246SAleksandr Popov IRBuilder<> B(PreheaderJump); 606483e9246SAleksandr Popov auto NoopOrExt = [&](Value *V) { 607483e9246SAleksandr Popov if (V->getType() == RangeTy) 608483e9246SAleksandr Popov return V; 609483e9246SAleksandr Popov return IsSignedPredicate ? B.CreateSExt(V, RangeTy, "wide." + V->getName()) 610483e9246SAleksandr Popov : B.CreateZExt(V, RangeTy, "wide." + V->getName()); 611483e9246SAleksandr Popov }; 612483e9246SAleksandr Popov 613483e9246SAleksandr Popov // EnterLoopCond - is it okay to start executing this `LS'? 614483e9246SAleksandr Popov Value *EnterLoopCond = nullptr; 615483e9246SAleksandr Popov auto Pred = 616483e9246SAleksandr Popov Increasing 617483e9246SAleksandr Popov ? (IsSignedPredicate ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT) 618483e9246SAleksandr Popov : (IsSignedPredicate ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT); 619483e9246SAleksandr Popov Value *IndVarStart = NoopOrExt(LS.IndVarStart); 620483e9246SAleksandr Popov EnterLoopCond = B.CreateICmp(Pred, IndVarStart, ExitSubloopAt); 621483e9246SAleksandr Popov 622483e9246SAleksandr Popov B.CreateCondBr(EnterLoopCond, LS.Header, RRI.PseudoExit); 623483e9246SAleksandr Popov PreheaderJump->eraseFromParent(); 624483e9246SAleksandr Popov 625483e9246SAleksandr Popov LS.LatchBr->setSuccessor(LS.LatchBrExitIdx, RRI.ExitSelector); 626483e9246SAleksandr Popov B.SetInsertPoint(LS.LatchBr); 627483e9246SAleksandr Popov Value *IndVarBase = NoopOrExt(LS.IndVarBase); 628483e9246SAleksandr Popov Value *TakeBackedgeLoopCond = B.CreateICmp(Pred, IndVarBase, ExitSubloopAt); 629483e9246SAleksandr Popov 630483e9246SAleksandr Popov Value *CondForBranch = LS.LatchBrExitIdx == 1 631483e9246SAleksandr Popov ? TakeBackedgeLoopCond 632483e9246SAleksandr Popov : B.CreateNot(TakeBackedgeLoopCond); 633483e9246SAleksandr Popov 634483e9246SAleksandr Popov LS.LatchBr->setCondition(CondForBranch); 635483e9246SAleksandr Popov 636483e9246SAleksandr Popov B.SetInsertPoint(RRI.ExitSelector); 637483e9246SAleksandr Popov 638483e9246SAleksandr Popov // IterationsLeft - are there any more iterations left, given the original 639483e9246SAleksandr Popov // upper bound on the induction variable? If not, we branch to the "real" 640483e9246SAleksandr Popov // exit. 641483e9246SAleksandr Popov Value *LoopExitAt = NoopOrExt(LS.LoopExitAt); 642483e9246SAleksandr Popov Value *IterationsLeft = B.CreateICmp(Pred, IndVarBase, LoopExitAt); 643483e9246SAleksandr Popov B.CreateCondBr(IterationsLeft, RRI.PseudoExit, LS.LatchExit); 644483e9246SAleksandr Popov 645483e9246SAleksandr Popov BranchInst *BranchToContinuation = 646483e9246SAleksandr Popov BranchInst::Create(ContinuationBlock, RRI.PseudoExit); 647483e9246SAleksandr Popov 648483e9246SAleksandr Popov // We emit PHI nodes into `RRI.PseudoExit' that compute the "latest" value of 649483e9246SAleksandr Popov // each of the PHI nodes in the loop header. This feeds into the initial 650483e9246SAleksandr Popov // value of the same PHI nodes if/when we continue execution. 651483e9246SAleksandr Popov for (PHINode &PN : LS.Header->phis()) { 652483e9246SAleksandr Popov PHINode *NewPHI = PHINode::Create(PN.getType(), 2, PN.getName() + ".copy", 6536b62a913SJeremy Morse BranchToContinuation->getIterator()); 654483e9246SAleksandr Popov 655483e9246SAleksandr Popov NewPHI->addIncoming(PN.getIncomingValueForBlock(Preheader), Preheader); 656483e9246SAleksandr Popov NewPHI->addIncoming(PN.getIncomingValueForBlock(LS.Latch), 657483e9246SAleksandr Popov RRI.ExitSelector); 658483e9246SAleksandr Popov RRI.PHIValuesAtPseudoExit.push_back(NewPHI); 659483e9246SAleksandr Popov } 660483e9246SAleksandr Popov 661483e9246SAleksandr Popov RRI.IndVarEnd = PHINode::Create(IndVarBase->getType(), 2, "indvar.end", 6626b62a913SJeremy Morse BranchToContinuation->getIterator()); 663483e9246SAleksandr Popov RRI.IndVarEnd->addIncoming(IndVarStart, Preheader); 664483e9246SAleksandr Popov RRI.IndVarEnd->addIncoming(IndVarBase, RRI.ExitSelector); 665483e9246SAleksandr Popov 666483e9246SAleksandr Popov // The latch exit now has a branch from `RRI.ExitSelector' instead of 667483e9246SAleksandr Popov // `LS.Latch'. The PHI nodes need to be updated to reflect that. 668483e9246SAleksandr Popov LS.LatchExit->replacePhiUsesWith(LS.Latch, RRI.ExitSelector); 669483e9246SAleksandr Popov 670483e9246SAleksandr Popov return RRI; 671483e9246SAleksandr Popov } 672483e9246SAleksandr Popov 673483e9246SAleksandr Popov void LoopConstrainer::rewriteIncomingValuesForPHIs( 674483e9246SAleksandr Popov LoopStructure &LS, BasicBlock *ContinuationBlock, 675483e9246SAleksandr Popov const LoopConstrainer::RewrittenRangeInfo &RRI) const { 676483e9246SAleksandr Popov unsigned PHIIndex = 0; 677483e9246SAleksandr Popov for (PHINode &PN : LS.Header->phis()) 678483e9246SAleksandr Popov PN.setIncomingValueForBlock(ContinuationBlock, 679483e9246SAleksandr Popov RRI.PHIValuesAtPseudoExit[PHIIndex++]); 680483e9246SAleksandr Popov 681483e9246SAleksandr Popov LS.IndVarStart = RRI.IndVarEnd; 682483e9246SAleksandr Popov } 683483e9246SAleksandr Popov 684483e9246SAleksandr Popov BasicBlock *LoopConstrainer::createPreheader(const LoopStructure &LS, 685483e9246SAleksandr Popov BasicBlock *OldPreheader, 686483e9246SAleksandr Popov const char *Tag) const { 687483e9246SAleksandr Popov BasicBlock *Preheader = BasicBlock::Create(Ctx, Tag, &F, LS.Header); 688483e9246SAleksandr Popov BranchInst::Create(LS.Header, Preheader); 689483e9246SAleksandr Popov 690483e9246SAleksandr Popov LS.Header->replacePhiUsesWith(OldPreheader, Preheader); 691483e9246SAleksandr Popov 692483e9246SAleksandr Popov return Preheader; 693483e9246SAleksandr Popov } 694483e9246SAleksandr Popov 695483e9246SAleksandr Popov void LoopConstrainer::addToParentLoopIfNeeded(ArrayRef<BasicBlock *> BBs) { 696483e9246SAleksandr Popov Loop *ParentLoop = OriginalLoop.getParentLoop(); 697483e9246SAleksandr Popov if (!ParentLoop) 698483e9246SAleksandr Popov return; 699483e9246SAleksandr Popov 700483e9246SAleksandr Popov for (BasicBlock *BB : BBs) 701483e9246SAleksandr Popov ParentLoop->addBasicBlockToLoop(BB, LI); 702483e9246SAleksandr Popov } 703483e9246SAleksandr Popov 704483e9246SAleksandr Popov Loop *LoopConstrainer::createClonedLoopStructure(Loop *Original, Loop *Parent, 705483e9246SAleksandr Popov ValueToValueMapTy &VM, 706483e9246SAleksandr Popov bool IsSubloop) { 707483e9246SAleksandr Popov Loop &New = *LI.AllocateLoop(); 708483e9246SAleksandr Popov if (Parent) 709483e9246SAleksandr Popov Parent->addChildLoop(&New); 710483e9246SAleksandr Popov else 711483e9246SAleksandr Popov LI.addTopLevelLoop(&New); 712483e9246SAleksandr Popov LPMAddNewLoop(&New, IsSubloop); 713483e9246SAleksandr Popov 714483e9246SAleksandr Popov // Add all of the blocks in Original to the new loop. 715483e9246SAleksandr Popov for (auto *BB : Original->blocks()) 716483e9246SAleksandr Popov if (LI.getLoopFor(BB) == Original) 717483e9246SAleksandr Popov New.addBasicBlockToLoop(cast<BasicBlock>(VM[BB]), LI); 718483e9246SAleksandr Popov 719483e9246SAleksandr Popov // Add all of the subloops to the new loop. 720483e9246SAleksandr Popov for (Loop *SubLoop : *Original) 721483e9246SAleksandr Popov createClonedLoopStructure(SubLoop, &New, VM, /* IsSubloop */ true); 722483e9246SAleksandr Popov 723483e9246SAleksandr Popov return &New; 724483e9246SAleksandr Popov } 725483e9246SAleksandr Popov 726483e9246SAleksandr Popov bool LoopConstrainer::run() { 727483e9246SAleksandr Popov BasicBlock *Preheader = OriginalLoop.getLoopPreheader(); 728483e9246SAleksandr Popov assert(Preheader != nullptr && "precondition!"); 729483e9246SAleksandr Popov 730483e9246SAleksandr Popov OriginalPreheader = Preheader; 731483e9246SAleksandr Popov MainLoopPreheader = Preheader; 732483e9246SAleksandr Popov bool IsSignedPredicate = MainLoopStructure.IsSignedPredicate; 733483e9246SAleksandr Popov bool Increasing = MainLoopStructure.IndVarIncreasing; 734483e9246SAleksandr Popov IntegerType *IVTy = cast<IntegerType>(RangeTy); 735483e9246SAleksandr Popov 7369df71d76SNikita Popov SCEVExpander Expander(SE, F.getDataLayout(), "loop-constrainer"); 737483e9246SAleksandr Popov Instruction *InsertPt = OriginalPreheader->getTerminator(); 738483e9246SAleksandr Popov 739483e9246SAleksandr Popov // It would have been better to make `PreLoop' and `PostLoop' 740483e9246SAleksandr Popov // `std::optional<ClonedLoop>'s, but `ValueToValueMapTy' does not have a copy 741483e9246SAleksandr Popov // constructor. 742483e9246SAleksandr Popov ClonedLoop PreLoop, PostLoop; 743483e9246SAleksandr Popov bool NeedsPreLoop = 744483e9246SAleksandr Popov Increasing ? SR.LowLimit.has_value() : SR.HighLimit.has_value(); 745483e9246SAleksandr Popov bool NeedsPostLoop = 746483e9246SAleksandr Popov Increasing ? SR.HighLimit.has_value() : SR.LowLimit.has_value(); 747483e9246SAleksandr Popov 748483e9246SAleksandr Popov Value *ExitPreLoopAt = nullptr; 749483e9246SAleksandr Popov Value *ExitMainLoopAt = nullptr; 750483e9246SAleksandr Popov const SCEVConstant *MinusOneS = 751483e9246SAleksandr Popov cast<SCEVConstant>(SE.getConstant(IVTy, -1, true /* isSigned */)); 752483e9246SAleksandr Popov 753483e9246SAleksandr Popov if (NeedsPreLoop) { 754483e9246SAleksandr Popov const SCEV *ExitPreLoopAtSCEV = nullptr; 755483e9246SAleksandr Popov 756483e9246SAleksandr Popov if (Increasing) 757483e9246SAleksandr Popov ExitPreLoopAtSCEV = *SR.LowLimit; 758483e9246SAleksandr Popov else if (cannotBeMinInLoop(*SR.HighLimit, &OriginalLoop, SE, 759483e9246SAleksandr Popov IsSignedPredicate)) 760483e9246SAleksandr Popov ExitPreLoopAtSCEV = SE.getAddExpr(*SR.HighLimit, MinusOneS); 761483e9246SAleksandr Popov else { 762483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "could not prove no-overflow when computing " 763483e9246SAleksandr Popov << "preloop exit limit. HighLimit = " 764483e9246SAleksandr Popov << *(*SR.HighLimit) << "\n"); 765483e9246SAleksandr Popov return false; 766483e9246SAleksandr Popov } 767483e9246SAleksandr Popov 768483e9246SAleksandr Popov if (!Expander.isSafeToExpandAt(ExitPreLoopAtSCEV, InsertPt)) { 769483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "could not prove that it is safe to expand the" 770483e9246SAleksandr Popov << " preloop exit limit " << *ExitPreLoopAtSCEV 771483e9246SAleksandr Popov << " at block " << InsertPt->getParent()->getName() 772483e9246SAleksandr Popov << "\n"); 773483e9246SAleksandr Popov return false; 774483e9246SAleksandr Popov } 775483e9246SAleksandr Popov 776483e9246SAleksandr Popov ExitPreLoopAt = Expander.expandCodeFor(ExitPreLoopAtSCEV, IVTy, InsertPt); 777483e9246SAleksandr Popov ExitPreLoopAt->setName("exit.preloop.at"); 778483e9246SAleksandr Popov } 779483e9246SAleksandr Popov 780483e9246SAleksandr Popov if (NeedsPostLoop) { 781483e9246SAleksandr Popov const SCEV *ExitMainLoopAtSCEV = nullptr; 782483e9246SAleksandr Popov 783483e9246SAleksandr Popov if (Increasing) 784483e9246SAleksandr Popov ExitMainLoopAtSCEV = *SR.HighLimit; 785483e9246SAleksandr Popov else if (cannotBeMinInLoop(*SR.LowLimit, &OriginalLoop, SE, 786483e9246SAleksandr Popov IsSignedPredicate)) 787483e9246SAleksandr Popov ExitMainLoopAtSCEV = SE.getAddExpr(*SR.LowLimit, MinusOneS); 788483e9246SAleksandr Popov else { 789483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "could not prove no-overflow when computing " 790483e9246SAleksandr Popov << "mainloop exit limit. LowLimit = " 791483e9246SAleksandr Popov << *(*SR.LowLimit) << "\n"); 792483e9246SAleksandr Popov return false; 793483e9246SAleksandr Popov } 794483e9246SAleksandr Popov 795483e9246SAleksandr Popov if (!Expander.isSafeToExpandAt(ExitMainLoopAtSCEV, InsertPt)) { 796483e9246SAleksandr Popov LLVM_DEBUG(dbgs() << "could not prove that it is safe to expand the" 797483e9246SAleksandr Popov << " main loop exit limit " << *ExitMainLoopAtSCEV 798483e9246SAleksandr Popov << " at block " << InsertPt->getParent()->getName() 799483e9246SAleksandr Popov << "\n"); 800483e9246SAleksandr Popov return false; 801483e9246SAleksandr Popov } 802483e9246SAleksandr Popov 803483e9246SAleksandr Popov ExitMainLoopAt = Expander.expandCodeFor(ExitMainLoopAtSCEV, IVTy, InsertPt); 804483e9246SAleksandr Popov ExitMainLoopAt->setName("exit.mainloop.at"); 805483e9246SAleksandr Popov } 806483e9246SAleksandr Popov 807483e9246SAleksandr Popov // We clone these ahead of time so that we don't have to deal with changing 808483e9246SAleksandr Popov // and temporarily invalid IR as we transform the loops. 809483e9246SAleksandr Popov if (NeedsPreLoop) 810483e9246SAleksandr Popov cloneLoop(PreLoop, "preloop"); 811483e9246SAleksandr Popov if (NeedsPostLoop) 812483e9246SAleksandr Popov cloneLoop(PostLoop, "postloop"); 813483e9246SAleksandr Popov 814483e9246SAleksandr Popov RewrittenRangeInfo PreLoopRRI; 815483e9246SAleksandr Popov 816483e9246SAleksandr Popov if (NeedsPreLoop) { 817483e9246SAleksandr Popov Preheader->getTerminator()->replaceUsesOfWith(MainLoopStructure.Header, 818483e9246SAleksandr Popov PreLoop.Structure.Header); 819483e9246SAleksandr Popov 820483e9246SAleksandr Popov MainLoopPreheader = 821483e9246SAleksandr Popov createPreheader(MainLoopStructure, Preheader, "mainloop"); 822483e9246SAleksandr Popov PreLoopRRI = changeIterationSpaceEnd(PreLoop.Structure, Preheader, 823483e9246SAleksandr Popov ExitPreLoopAt, MainLoopPreheader); 824483e9246SAleksandr Popov rewriteIncomingValuesForPHIs(MainLoopStructure, MainLoopPreheader, 825483e9246SAleksandr Popov PreLoopRRI); 826483e9246SAleksandr Popov } 827483e9246SAleksandr Popov 828483e9246SAleksandr Popov BasicBlock *PostLoopPreheader = nullptr; 829483e9246SAleksandr Popov RewrittenRangeInfo PostLoopRRI; 830483e9246SAleksandr Popov 831483e9246SAleksandr Popov if (NeedsPostLoop) { 832483e9246SAleksandr Popov PostLoopPreheader = 833483e9246SAleksandr Popov createPreheader(PostLoop.Structure, Preheader, "postloop"); 834483e9246SAleksandr Popov PostLoopRRI = changeIterationSpaceEnd(MainLoopStructure, MainLoopPreheader, 835483e9246SAleksandr Popov ExitMainLoopAt, PostLoopPreheader); 836483e9246SAleksandr Popov rewriteIncomingValuesForPHIs(PostLoop.Structure, PostLoopPreheader, 837483e9246SAleksandr Popov PostLoopRRI); 838483e9246SAleksandr Popov } 839483e9246SAleksandr Popov 840483e9246SAleksandr Popov BasicBlock *NewMainLoopPreheader = 841483e9246SAleksandr Popov MainLoopPreheader != Preheader ? MainLoopPreheader : nullptr; 842483e9246SAleksandr Popov BasicBlock *NewBlocks[] = {PostLoopPreheader, PreLoopRRI.PseudoExit, 843483e9246SAleksandr Popov PreLoopRRI.ExitSelector, PostLoopRRI.PseudoExit, 844483e9246SAleksandr Popov PostLoopRRI.ExitSelector, NewMainLoopPreheader}; 845483e9246SAleksandr Popov 846483e9246SAleksandr Popov // Some of the above may be nullptr, filter them out before passing to 847483e9246SAleksandr Popov // addToParentLoopIfNeeded. 848483e9246SAleksandr Popov auto NewBlocksEnd = 849483e9246SAleksandr Popov std::remove(std::begin(NewBlocks), std::end(NewBlocks), nullptr); 850483e9246SAleksandr Popov 851483e9246SAleksandr Popov addToParentLoopIfNeeded(ArrayRef(std::begin(NewBlocks), NewBlocksEnd)); 852483e9246SAleksandr Popov 853483e9246SAleksandr Popov DT.recalculate(F); 854483e9246SAleksandr Popov 855483e9246SAleksandr Popov // We need to first add all the pre and post loop blocks into the loop 856483e9246SAleksandr Popov // structures (as part of createClonedLoopStructure), and then update the 857483e9246SAleksandr Popov // LCSSA form and LoopSimplifyForm. This is necessary for correctly updating 858483e9246SAleksandr Popov // LI when LoopSimplifyForm is generated. 859483e9246SAleksandr Popov Loop *PreL = nullptr, *PostL = nullptr; 860483e9246SAleksandr Popov if (!PreLoop.Blocks.empty()) { 861483e9246SAleksandr Popov PreL = createClonedLoopStructure(&OriginalLoop, 862483e9246SAleksandr Popov OriginalLoop.getParentLoop(), PreLoop.Map, 863483e9246SAleksandr Popov /* IsSubLoop */ false); 864483e9246SAleksandr Popov } 865483e9246SAleksandr Popov 866483e9246SAleksandr Popov if (!PostLoop.Blocks.empty()) { 867483e9246SAleksandr Popov PostL = 868483e9246SAleksandr Popov createClonedLoopStructure(&OriginalLoop, OriginalLoop.getParentLoop(), 869483e9246SAleksandr Popov PostLoop.Map, /* IsSubLoop */ false); 870483e9246SAleksandr Popov } 871483e9246SAleksandr Popov 872483e9246SAleksandr Popov // This function canonicalizes the loop into Loop-Simplify and LCSSA forms. 873483e9246SAleksandr Popov auto CanonicalizeLoop = [&](Loop *L, bool IsOriginalLoop) { 874483e9246SAleksandr Popov formLCSSARecursively(*L, DT, &LI, &SE); 875483e9246SAleksandr Popov simplifyLoop(L, &DT, &LI, &SE, nullptr, nullptr, true); 876483e9246SAleksandr Popov // Pre/post loops are slow paths, we do not need to perform any loop 877483e9246SAleksandr Popov // optimizations on them. 878483e9246SAleksandr Popov if (!IsOriginalLoop) 879483e9246SAleksandr Popov DisableAllLoopOptsOnLoop(*L); 880483e9246SAleksandr Popov }; 881483e9246SAleksandr Popov if (PreL) 882483e9246SAleksandr Popov CanonicalizeLoop(PreL, false); 883483e9246SAleksandr Popov if (PostL) 884483e9246SAleksandr Popov CanonicalizeLoop(PostL, false); 885483e9246SAleksandr Popov CanonicalizeLoop(&OriginalLoop, true); 886483e9246SAleksandr Popov 887483e9246SAleksandr Popov /// At this point: 888483e9246SAleksandr Popov /// - We've broken a "main loop" out of the loop in a way that the "main loop" 889483e9246SAleksandr Popov /// runs with the induction variable in a subset of [Begin, End). 890483e9246SAleksandr Popov /// - There is no overflow when computing "main loop" exit limit. 891483e9246SAleksandr Popov /// - Max latch taken count of the loop is limited. 892483e9246SAleksandr Popov /// It guarantees that induction variable will not overflow iterating in the 893483e9246SAleksandr Popov /// "main loop". 894483e9246SAleksandr Popov if (isa<OverflowingBinaryOperator>(MainLoopStructure.IndVarBase)) 895483e9246SAleksandr Popov if (IsSignedPredicate) 896483e9246SAleksandr Popov cast<BinaryOperator>(MainLoopStructure.IndVarBase) 897483e9246SAleksandr Popov ->setHasNoSignedWrap(true); 898483e9246SAleksandr Popov /// TODO: support unsigned predicate. 899483e9246SAleksandr Popov /// To add NUW flag we need to prove that both operands of BO are 900483e9246SAleksandr Popov /// non-negative. E.g: 901483e9246SAleksandr Popov /// ... 902483e9246SAleksandr Popov /// %iv.next = add nsw i32 %iv, -1 903483e9246SAleksandr Popov /// %cmp = icmp ult i32 %iv.next, %n 904483e9246SAleksandr Popov /// br i1 %cmp, label %loopexit, label %loop 905483e9246SAleksandr Popov /// 906483e9246SAleksandr Popov /// -1 is MAX_UINT in terms of unsigned int. Adding anything but zero will 907483e9246SAleksandr Popov /// overflow, therefore NUW flag is not legal here. 908483e9246SAleksandr Popov 909483e9246SAleksandr Popov return true; 910483e9246SAleksandr Popov } 911