1*0b57cec5SDimitry Andric //===-- LoopUtils.cpp - Loop Utility functions -------------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file defines common loop utility functions. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #include "llvm/Transforms/Utils/LoopUtils.h" 14*0b57cec5SDimitry Andric #include "llvm/ADT/ScopeExit.h" 15*0b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h" 16*0b57cec5SDimitry Andric #include "llvm/Analysis/BasicAliasAnalysis.h" 17*0b57cec5SDimitry Andric #include "llvm/Analysis/DomTreeUpdater.h" 18*0b57cec5SDimitry Andric #include "llvm/Analysis/GlobalsModRef.h" 19*0b57cec5SDimitry Andric #include "llvm/Analysis/InstructionSimplify.h" 20*0b57cec5SDimitry Andric #include "llvm/Analysis/LoopInfo.h" 21*0b57cec5SDimitry Andric #include "llvm/Analysis/LoopPass.h" 22*0b57cec5SDimitry Andric #include "llvm/Analysis/MemorySSAUpdater.h" 23*0b57cec5SDimitry Andric #include "llvm/Analysis/MustExecute.h" 24*0b57cec5SDimitry Andric #include "llvm/Analysis/ScalarEvolution.h" 25*0b57cec5SDimitry Andric #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" 26*0b57cec5SDimitry Andric #include "llvm/Analysis/ScalarEvolutionExpander.h" 27*0b57cec5SDimitry Andric #include "llvm/Analysis/ScalarEvolutionExpressions.h" 28*0b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h" 29*0b57cec5SDimitry Andric #include "llvm/Analysis/ValueTracking.h" 30*0b57cec5SDimitry Andric #include "llvm/IR/DIBuilder.h" 31*0b57cec5SDimitry Andric #include "llvm/IR/Dominators.h" 32*0b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 33*0b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h" 34*0b57cec5SDimitry Andric #include "llvm/IR/Module.h" 35*0b57cec5SDimitry Andric #include "llvm/IR/PatternMatch.h" 36*0b57cec5SDimitry Andric #include "llvm/IR/ValueHandle.h" 37*0b57cec5SDimitry Andric #include "llvm/Pass.h" 38*0b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 39*0b57cec5SDimitry Andric #include "llvm/Support/KnownBits.h" 40*0b57cec5SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h" 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric using namespace llvm; 43*0b57cec5SDimitry Andric using namespace llvm::PatternMatch; 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andric #define DEBUG_TYPE "loop-utils" 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric static const char *LLVMLoopDisableNonforced = "llvm.loop.disable_nonforced"; 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric bool llvm::formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI, 50*0b57cec5SDimitry Andric MemorySSAUpdater *MSSAU, 51*0b57cec5SDimitry Andric bool PreserveLCSSA) { 52*0b57cec5SDimitry Andric bool Changed = false; 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric // We re-use a vector for the in-loop predecesosrs. 55*0b57cec5SDimitry Andric SmallVector<BasicBlock *, 4> InLoopPredecessors; 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric auto RewriteExit = [&](BasicBlock *BB) { 58*0b57cec5SDimitry Andric assert(InLoopPredecessors.empty() && 59*0b57cec5SDimitry Andric "Must start with an empty predecessors list!"); 60*0b57cec5SDimitry Andric auto Cleanup = make_scope_exit([&] { InLoopPredecessors.clear(); }); 61*0b57cec5SDimitry Andric 62*0b57cec5SDimitry Andric // See if there are any non-loop predecessors of this exit block and 63*0b57cec5SDimitry Andric // keep track of the in-loop predecessors. 64*0b57cec5SDimitry Andric bool IsDedicatedExit = true; 65*0b57cec5SDimitry Andric for (auto *PredBB : predecessors(BB)) 66*0b57cec5SDimitry Andric if (L->contains(PredBB)) { 67*0b57cec5SDimitry Andric if (isa<IndirectBrInst>(PredBB->getTerminator())) 68*0b57cec5SDimitry Andric // We cannot rewrite exiting edges from an indirectbr. 69*0b57cec5SDimitry Andric return false; 70*0b57cec5SDimitry Andric if (isa<CallBrInst>(PredBB->getTerminator())) 71*0b57cec5SDimitry Andric // We cannot rewrite exiting edges from a callbr. 72*0b57cec5SDimitry Andric return false; 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric InLoopPredecessors.push_back(PredBB); 75*0b57cec5SDimitry Andric } else { 76*0b57cec5SDimitry Andric IsDedicatedExit = false; 77*0b57cec5SDimitry Andric } 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andric assert(!InLoopPredecessors.empty() && "Must have *some* loop predecessor!"); 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andric // Nothing to do if this is already a dedicated exit. 82*0b57cec5SDimitry Andric if (IsDedicatedExit) 83*0b57cec5SDimitry Andric return false; 84*0b57cec5SDimitry Andric 85*0b57cec5SDimitry Andric auto *NewExitBB = SplitBlockPredecessors( 86*0b57cec5SDimitry Andric BB, InLoopPredecessors, ".loopexit", DT, LI, MSSAU, PreserveLCSSA); 87*0b57cec5SDimitry Andric 88*0b57cec5SDimitry Andric if (!NewExitBB) 89*0b57cec5SDimitry Andric LLVM_DEBUG( 90*0b57cec5SDimitry Andric dbgs() << "WARNING: Can't create a dedicated exit block for loop: " 91*0b57cec5SDimitry Andric << *L << "\n"); 92*0b57cec5SDimitry Andric else 93*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "LoopSimplify: Creating dedicated exit block " 94*0b57cec5SDimitry Andric << NewExitBB->getName() << "\n"); 95*0b57cec5SDimitry Andric return true; 96*0b57cec5SDimitry Andric }; 97*0b57cec5SDimitry Andric 98*0b57cec5SDimitry Andric // Walk the exit blocks directly rather than building up a data structure for 99*0b57cec5SDimitry Andric // them, but only visit each one once. 100*0b57cec5SDimitry Andric SmallPtrSet<BasicBlock *, 4> Visited; 101*0b57cec5SDimitry Andric for (auto *BB : L->blocks()) 102*0b57cec5SDimitry Andric for (auto *SuccBB : successors(BB)) { 103*0b57cec5SDimitry Andric // We're looking for exit blocks so skip in-loop successors. 104*0b57cec5SDimitry Andric if (L->contains(SuccBB)) 105*0b57cec5SDimitry Andric continue; 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric // Visit each exit block exactly once. 108*0b57cec5SDimitry Andric if (!Visited.insert(SuccBB).second) 109*0b57cec5SDimitry Andric continue; 110*0b57cec5SDimitry Andric 111*0b57cec5SDimitry Andric Changed |= RewriteExit(SuccBB); 112*0b57cec5SDimitry Andric } 113*0b57cec5SDimitry Andric 114*0b57cec5SDimitry Andric return Changed; 115*0b57cec5SDimitry Andric } 116*0b57cec5SDimitry Andric 117*0b57cec5SDimitry Andric /// Returns the instructions that use values defined in the loop. 118*0b57cec5SDimitry Andric SmallVector<Instruction *, 8> llvm::findDefsUsedOutsideOfLoop(Loop *L) { 119*0b57cec5SDimitry Andric SmallVector<Instruction *, 8> UsedOutside; 120*0b57cec5SDimitry Andric 121*0b57cec5SDimitry Andric for (auto *Block : L->getBlocks()) 122*0b57cec5SDimitry Andric // FIXME: I believe that this could use copy_if if the Inst reference could 123*0b57cec5SDimitry Andric // be adapted into a pointer. 124*0b57cec5SDimitry Andric for (auto &Inst : *Block) { 125*0b57cec5SDimitry Andric auto Users = Inst.users(); 126*0b57cec5SDimitry Andric if (any_of(Users, [&](User *U) { 127*0b57cec5SDimitry Andric auto *Use = cast<Instruction>(U); 128*0b57cec5SDimitry Andric return !L->contains(Use->getParent()); 129*0b57cec5SDimitry Andric })) 130*0b57cec5SDimitry Andric UsedOutside.push_back(&Inst); 131*0b57cec5SDimitry Andric } 132*0b57cec5SDimitry Andric 133*0b57cec5SDimitry Andric return UsedOutside; 134*0b57cec5SDimitry Andric } 135*0b57cec5SDimitry Andric 136*0b57cec5SDimitry Andric void llvm::getLoopAnalysisUsage(AnalysisUsage &AU) { 137*0b57cec5SDimitry Andric // By definition, all loop passes need the LoopInfo analysis and the 138*0b57cec5SDimitry Andric // Dominator tree it depends on. Because they all participate in the loop 139*0b57cec5SDimitry Andric // pass manager, they must also preserve these. 140*0b57cec5SDimitry Andric AU.addRequired<DominatorTreeWrapperPass>(); 141*0b57cec5SDimitry Andric AU.addPreserved<DominatorTreeWrapperPass>(); 142*0b57cec5SDimitry Andric AU.addRequired<LoopInfoWrapperPass>(); 143*0b57cec5SDimitry Andric AU.addPreserved<LoopInfoWrapperPass>(); 144*0b57cec5SDimitry Andric 145*0b57cec5SDimitry Andric // We must also preserve LoopSimplify and LCSSA. We locally access their IDs 146*0b57cec5SDimitry Andric // here because users shouldn't directly get them from this header. 147*0b57cec5SDimitry Andric extern char &LoopSimplifyID; 148*0b57cec5SDimitry Andric extern char &LCSSAID; 149*0b57cec5SDimitry Andric AU.addRequiredID(LoopSimplifyID); 150*0b57cec5SDimitry Andric AU.addPreservedID(LoopSimplifyID); 151*0b57cec5SDimitry Andric AU.addRequiredID(LCSSAID); 152*0b57cec5SDimitry Andric AU.addPreservedID(LCSSAID); 153*0b57cec5SDimitry Andric // This is used in the LPPassManager to perform LCSSA verification on passes 154*0b57cec5SDimitry Andric // which preserve lcssa form 155*0b57cec5SDimitry Andric AU.addRequired<LCSSAVerificationPass>(); 156*0b57cec5SDimitry Andric AU.addPreserved<LCSSAVerificationPass>(); 157*0b57cec5SDimitry Andric 158*0b57cec5SDimitry Andric // Loop passes are designed to run inside of a loop pass manager which means 159*0b57cec5SDimitry Andric // that any function analyses they require must be required by the first loop 160*0b57cec5SDimitry Andric // pass in the manager (so that it is computed before the loop pass manager 161*0b57cec5SDimitry Andric // runs) and preserved by all loop pasess in the manager. To make this 162*0b57cec5SDimitry Andric // reasonably robust, the set needed for most loop passes is maintained here. 163*0b57cec5SDimitry Andric // If your loop pass requires an analysis not listed here, you will need to 164*0b57cec5SDimitry Andric // carefully audit the loop pass manager nesting structure that results. 165*0b57cec5SDimitry Andric AU.addRequired<AAResultsWrapperPass>(); 166*0b57cec5SDimitry Andric AU.addPreserved<AAResultsWrapperPass>(); 167*0b57cec5SDimitry Andric AU.addPreserved<BasicAAWrapperPass>(); 168*0b57cec5SDimitry Andric AU.addPreserved<GlobalsAAWrapperPass>(); 169*0b57cec5SDimitry Andric AU.addPreserved<SCEVAAWrapperPass>(); 170*0b57cec5SDimitry Andric AU.addRequired<ScalarEvolutionWrapperPass>(); 171*0b57cec5SDimitry Andric AU.addPreserved<ScalarEvolutionWrapperPass>(); 172*0b57cec5SDimitry Andric } 173*0b57cec5SDimitry Andric 174*0b57cec5SDimitry Andric /// Manually defined generic "LoopPass" dependency initialization. This is used 175*0b57cec5SDimitry Andric /// to initialize the exact set of passes from above in \c 176*0b57cec5SDimitry Andric /// getLoopAnalysisUsage. It can be used within a loop pass's initialization 177*0b57cec5SDimitry Andric /// with: 178*0b57cec5SDimitry Andric /// 179*0b57cec5SDimitry Andric /// INITIALIZE_PASS_DEPENDENCY(LoopPass) 180*0b57cec5SDimitry Andric /// 181*0b57cec5SDimitry Andric /// As-if "LoopPass" were a pass. 182*0b57cec5SDimitry Andric void llvm::initializeLoopPassPass(PassRegistry &Registry) { 183*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 184*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) 185*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LoopSimplify) 186*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LCSSAWrapperPass) 187*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) 188*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass) 189*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) 190*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass) 191*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) 192*0b57cec5SDimitry Andric } 193*0b57cec5SDimitry Andric 194*0b57cec5SDimitry Andric /// Find string metadata for loop 195*0b57cec5SDimitry Andric /// 196*0b57cec5SDimitry Andric /// If it has a value (e.g. {"llvm.distribute", 1} return the value as an 197*0b57cec5SDimitry Andric /// operand or null otherwise. If the string metadata is not found return 198*0b57cec5SDimitry Andric /// Optional's not-a-value. 199*0b57cec5SDimitry Andric Optional<const MDOperand *> llvm::findStringMetadataForLoop(const Loop *TheLoop, 200*0b57cec5SDimitry Andric StringRef Name) { 201*0b57cec5SDimitry Andric MDNode *MD = findOptionMDForLoop(TheLoop, Name); 202*0b57cec5SDimitry Andric if (!MD) 203*0b57cec5SDimitry Andric return None; 204*0b57cec5SDimitry Andric switch (MD->getNumOperands()) { 205*0b57cec5SDimitry Andric case 1: 206*0b57cec5SDimitry Andric return nullptr; 207*0b57cec5SDimitry Andric case 2: 208*0b57cec5SDimitry Andric return &MD->getOperand(1); 209*0b57cec5SDimitry Andric default: 210*0b57cec5SDimitry Andric llvm_unreachable("loop metadata has 0 or 1 operand"); 211*0b57cec5SDimitry Andric } 212*0b57cec5SDimitry Andric } 213*0b57cec5SDimitry Andric 214*0b57cec5SDimitry Andric static Optional<bool> getOptionalBoolLoopAttribute(const Loop *TheLoop, 215*0b57cec5SDimitry Andric StringRef Name) { 216*0b57cec5SDimitry Andric MDNode *MD = findOptionMDForLoop(TheLoop, Name); 217*0b57cec5SDimitry Andric if (!MD) 218*0b57cec5SDimitry Andric return None; 219*0b57cec5SDimitry Andric switch (MD->getNumOperands()) { 220*0b57cec5SDimitry Andric case 1: 221*0b57cec5SDimitry Andric // When the value is absent it is interpreted as 'attribute set'. 222*0b57cec5SDimitry Andric return true; 223*0b57cec5SDimitry Andric case 2: 224*0b57cec5SDimitry Andric if (ConstantInt *IntMD = 225*0b57cec5SDimitry Andric mdconst::extract_or_null<ConstantInt>(MD->getOperand(1).get())) 226*0b57cec5SDimitry Andric return IntMD->getZExtValue(); 227*0b57cec5SDimitry Andric return true; 228*0b57cec5SDimitry Andric } 229*0b57cec5SDimitry Andric llvm_unreachable("unexpected number of options"); 230*0b57cec5SDimitry Andric } 231*0b57cec5SDimitry Andric 232*0b57cec5SDimitry Andric static bool getBooleanLoopAttribute(const Loop *TheLoop, StringRef Name) { 233*0b57cec5SDimitry Andric return getOptionalBoolLoopAttribute(TheLoop, Name).getValueOr(false); 234*0b57cec5SDimitry Andric } 235*0b57cec5SDimitry Andric 236*0b57cec5SDimitry Andric llvm::Optional<int> llvm::getOptionalIntLoopAttribute(Loop *TheLoop, 237*0b57cec5SDimitry Andric StringRef Name) { 238*0b57cec5SDimitry Andric const MDOperand *AttrMD = 239*0b57cec5SDimitry Andric findStringMetadataForLoop(TheLoop, Name).getValueOr(nullptr); 240*0b57cec5SDimitry Andric if (!AttrMD) 241*0b57cec5SDimitry Andric return None; 242*0b57cec5SDimitry Andric 243*0b57cec5SDimitry Andric ConstantInt *IntMD = mdconst::extract_or_null<ConstantInt>(AttrMD->get()); 244*0b57cec5SDimitry Andric if (!IntMD) 245*0b57cec5SDimitry Andric return None; 246*0b57cec5SDimitry Andric 247*0b57cec5SDimitry Andric return IntMD->getSExtValue(); 248*0b57cec5SDimitry Andric } 249*0b57cec5SDimitry Andric 250*0b57cec5SDimitry Andric Optional<MDNode *> llvm::makeFollowupLoopID( 251*0b57cec5SDimitry Andric MDNode *OrigLoopID, ArrayRef<StringRef> FollowupOptions, 252*0b57cec5SDimitry Andric const char *InheritOptionsExceptPrefix, bool AlwaysNew) { 253*0b57cec5SDimitry Andric if (!OrigLoopID) { 254*0b57cec5SDimitry Andric if (AlwaysNew) 255*0b57cec5SDimitry Andric return nullptr; 256*0b57cec5SDimitry Andric return None; 257*0b57cec5SDimitry Andric } 258*0b57cec5SDimitry Andric 259*0b57cec5SDimitry Andric assert(OrigLoopID->getOperand(0) == OrigLoopID); 260*0b57cec5SDimitry Andric 261*0b57cec5SDimitry Andric bool InheritAllAttrs = !InheritOptionsExceptPrefix; 262*0b57cec5SDimitry Andric bool InheritSomeAttrs = 263*0b57cec5SDimitry Andric InheritOptionsExceptPrefix && InheritOptionsExceptPrefix[0] != '\0'; 264*0b57cec5SDimitry Andric SmallVector<Metadata *, 8> MDs; 265*0b57cec5SDimitry Andric MDs.push_back(nullptr); 266*0b57cec5SDimitry Andric 267*0b57cec5SDimitry Andric bool Changed = false; 268*0b57cec5SDimitry Andric if (InheritAllAttrs || InheritSomeAttrs) { 269*0b57cec5SDimitry Andric for (const MDOperand &Existing : drop_begin(OrigLoopID->operands(), 1)) { 270*0b57cec5SDimitry Andric MDNode *Op = cast<MDNode>(Existing.get()); 271*0b57cec5SDimitry Andric 272*0b57cec5SDimitry Andric auto InheritThisAttribute = [InheritSomeAttrs, 273*0b57cec5SDimitry Andric InheritOptionsExceptPrefix](MDNode *Op) { 274*0b57cec5SDimitry Andric if (!InheritSomeAttrs) 275*0b57cec5SDimitry Andric return false; 276*0b57cec5SDimitry Andric 277*0b57cec5SDimitry Andric // Skip malformatted attribute metadata nodes. 278*0b57cec5SDimitry Andric if (Op->getNumOperands() == 0) 279*0b57cec5SDimitry Andric return true; 280*0b57cec5SDimitry Andric Metadata *NameMD = Op->getOperand(0).get(); 281*0b57cec5SDimitry Andric if (!isa<MDString>(NameMD)) 282*0b57cec5SDimitry Andric return true; 283*0b57cec5SDimitry Andric StringRef AttrName = cast<MDString>(NameMD)->getString(); 284*0b57cec5SDimitry Andric 285*0b57cec5SDimitry Andric // Do not inherit excluded attributes. 286*0b57cec5SDimitry Andric return !AttrName.startswith(InheritOptionsExceptPrefix); 287*0b57cec5SDimitry Andric }; 288*0b57cec5SDimitry Andric 289*0b57cec5SDimitry Andric if (InheritThisAttribute(Op)) 290*0b57cec5SDimitry Andric MDs.push_back(Op); 291*0b57cec5SDimitry Andric else 292*0b57cec5SDimitry Andric Changed = true; 293*0b57cec5SDimitry Andric } 294*0b57cec5SDimitry Andric } else { 295*0b57cec5SDimitry Andric // Modified if we dropped at least one attribute. 296*0b57cec5SDimitry Andric Changed = OrigLoopID->getNumOperands() > 1; 297*0b57cec5SDimitry Andric } 298*0b57cec5SDimitry Andric 299*0b57cec5SDimitry Andric bool HasAnyFollowup = false; 300*0b57cec5SDimitry Andric for (StringRef OptionName : FollowupOptions) { 301*0b57cec5SDimitry Andric MDNode *FollowupNode = findOptionMDForLoopID(OrigLoopID, OptionName); 302*0b57cec5SDimitry Andric if (!FollowupNode) 303*0b57cec5SDimitry Andric continue; 304*0b57cec5SDimitry Andric 305*0b57cec5SDimitry Andric HasAnyFollowup = true; 306*0b57cec5SDimitry Andric for (const MDOperand &Option : drop_begin(FollowupNode->operands(), 1)) { 307*0b57cec5SDimitry Andric MDs.push_back(Option.get()); 308*0b57cec5SDimitry Andric Changed = true; 309*0b57cec5SDimitry Andric } 310*0b57cec5SDimitry Andric } 311*0b57cec5SDimitry Andric 312*0b57cec5SDimitry Andric // Attributes of the followup loop not specified explicity, so signal to the 313*0b57cec5SDimitry Andric // transformation pass to add suitable attributes. 314*0b57cec5SDimitry Andric if (!AlwaysNew && !HasAnyFollowup) 315*0b57cec5SDimitry Andric return None; 316*0b57cec5SDimitry Andric 317*0b57cec5SDimitry Andric // If no attributes were added or remove, the previous loop Id can be reused. 318*0b57cec5SDimitry Andric if (!AlwaysNew && !Changed) 319*0b57cec5SDimitry Andric return OrigLoopID; 320*0b57cec5SDimitry Andric 321*0b57cec5SDimitry Andric // No attributes is equivalent to having no !llvm.loop metadata at all. 322*0b57cec5SDimitry Andric if (MDs.size() == 1) 323*0b57cec5SDimitry Andric return nullptr; 324*0b57cec5SDimitry Andric 325*0b57cec5SDimitry Andric // Build the new loop ID. 326*0b57cec5SDimitry Andric MDTuple *FollowupLoopID = MDNode::get(OrigLoopID->getContext(), MDs); 327*0b57cec5SDimitry Andric FollowupLoopID->replaceOperandWith(0, FollowupLoopID); 328*0b57cec5SDimitry Andric return FollowupLoopID; 329*0b57cec5SDimitry Andric } 330*0b57cec5SDimitry Andric 331*0b57cec5SDimitry Andric bool llvm::hasDisableAllTransformsHint(const Loop *L) { 332*0b57cec5SDimitry Andric return getBooleanLoopAttribute(L, LLVMLoopDisableNonforced); 333*0b57cec5SDimitry Andric } 334*0b57cec5SDimitry Andric 335*0b57cec5SDimitry Andric TransformationMode llvm::hasUnrollTransformation(Loop *L) { 336*0b57cec5SDimitry Andric if (getBooleanLoopAttribute(L, "llvm.loop.unroll.disable")) 337*0b57cec5SDimitry Andric return TM_SuppressedByUser; 338*0b57cec5SDimitry Andric 339*0b57cec5SDimitry Andric Optional<int> Count = 340*0b57cec5SDimitry Andric getOptionalIntLoopAttribute(L, "llvm.loop.unroll.count"); 341*0b57cec5SDimitry Andric if (Count.hasValue()) 342*0b57cec5SDimitry Andric return Count.getValue() == 1 ? TM_SuppressedByUser : TM_ForcedByUser; 343*0b57cec5SDimitry Andric 344*0b57cec5SDimitry Andric if (getBooleanLoopAttribute(L, "llvm.loop.unroll.enable")) 345*0b57cec5SDimitry Andric return TM_ForcedByUser; 346*0b57cec5SDimitry Andric 347*0b57cec5SDimitry Andric if (getBooleanLoopAttribute(L, "llvm.loop.unroll.full")) 348*0b57cec5SDimitry Andric return TM_ForcedByUser; 349*0b57cec5SDimitry Andric 350*0b57cec5SDimitry Andric if (hasDisableAllTransformsHint(L)) 351*0b57cec5SDimitry Andric return TM_Disable; 352*0b57cec5SDimitry Andric 353*0b57cec5SDimitry Andric return TM_Unspecified; 354*0b57cec5SDimitry Andric } 355*0b57cec5SDimitry Andric 356*0b57cec5SDimitry Andric TransformationMode llvm::hasUnrollAndJamTransformation(Loop *L) { 357*0b57cec5SDimitry Andric if (getBooleanLoopAttribute(L, "llvm.loop.unroll_and_jam.disable")) 358*0b57cec5SDimitry Andric return TM_SuppressedByUser; 359*0b57cec5SDimitry Andric 360*0b57cec5SDimitry Andric Optional<int> Count = 361*0b57cec5SDimitry Andric getOptionalIntLoopAttribute(L, "llvm.loop.unroll_and_jam.count"); 362*0b57cec5SDimitry Andric if (Count.hasValue()) 363*0b57cec5SDimitry Andric return Count.getValue() == 1 ? TM_SuppressedByUser : TM_ForcedByUser; 364*0b57cec5SDimitry Andric 365*0b57cec5SDimitry Andric if (getBooleanLoopAttribute(L, "llvm.loop.unroll_and_jam.enable")) 366*0b57cec5SDimitry Andric return TM_ForcedByUser; 367*0b57cec5SDimitry Andric 368*0b57cec5SDimitry Andric if (hasDisableAllTransformsHint(L)) 369*0b57cec5SDimitry Andric return TM_Disable; 370*0b57cec5SDimitry Andric 371*0b57cec5SDimitry Andric return TM_Unspecified; 372*0b57cec5SDimitry Andric } 373*0b57cec5SDimitry Andric 374*0b57cec5SDimitry Andric TransformationMode llvm::hasVectorizeTransformation(Loop *L) { 375*0b57cec5SDimitry Andric Optional<bool> Enable = 376*0b57cec5SDimitry Andric getOptionalBoolLoopAttribute(L, "llvm.loop.vectorize.enable"); 377*0b57cec5SDimitry Andric 378*0b57cec5SDimitry Andric if (Enable == false) 379*0b57cec5SDimitry Andric return TM_SuppressedByUser; 380*0b57cec5SDimitry Andric 381*0b57cec5SDimitry Andric Optional<int> VectorizeWidth = 382*0b57cec5SDimitry Andric getOptionalIntLoopAttribute(L, "llvm.loop.vectorize.width"); 383*0b57cec5SDimitry Andric Optional<int> InterleaveCount = 384*0b57cec5SDimitry Andric getOptionalIntLoopAttribute(L, "llvm.loop.interleave.count"); 385*0b57cec5SDimitry Andric 386*0b57cec5SDimitry Andric // 'Forcing' vector width and interleave count to one effectively disables 387*0b57cec5SDimitry Andric // this tranformation. 388*0b57cec5SDimitry Andric if (Enable == true && VectorizeWidth == 1 && InterleaveCount == 1) 389*0b57cec5SDimitry Andric return TM_SuppressedByUser; 390*0b57cec5SDimitry Andric 391*0b57cec5SDimitry Andric if (getBooleanLoopAttribute(L, "llvm.loop.isvectorized")) 392*0b57cec5SDimitry Andric return TM_Disable; 393*0b57cec5SDimitry Andric 394*0b57cec5SDimitry Andric if (Enable == true) 395*0b57cec5SDimitry Andric return TM_ForcedByUser; 396*0b57cec5SDimitry Andric 397*0b57cec5SDimitry Andric if (VectorizeWidth == 1 && InterleaveCount == 1) 398*0b57cec5SDimitry Andric return TM_Disable; 399*0b57cec5SDimitry Andric 400*0b57cec5SDimitry Andric if (VectorizeWidth > 1 || InterleaveCount > 1) 401*0b57cec5SDimitry Andric return TM_Enable; 402*0b57cec5SDimitry Andric 403*0b57cec5SDimitry Andric if (hasDisableAllTransformsHint(L)) 404*0b57cec5SDimitry Andric return TM_Disable; 405*0b57cec5SDimitry Andric 406*0b57cec5SDimitry Andric return TM_Unspecified; 407*0b57cec5SDimitry Andric } 408*0b57cec5SDimitry Andric 409*0b57cec5SDimitry Andric TransformationMode llvm::hasDistributeTransformation(Loop *L) { 410*0b57cec5SDimitry Andric if (getBooleanLoopAttribute(L, "llvm.loop.distribute.enable")) 411*0b57cec5SDimitry Andric return TM_ForcedByUser; 412*0b57cec5SDimitry Andric 413*0b57cec5SDimitry Andric if (hasDisableAllTransformsHint(L)) 414*0b57cec5SDimitry Andric return TM_Disable; 415*0b57cec5SDimitry Andric 416*0b57cec5SDimitry Andric return TM_Unspecified; 417*0b57cec5SDimitry Andric } 418*0b57cec5SDimitry Andric 419*0b57cec5SDimitry Andric TransformationMode llvm::hasLICMVersioningTransformation(Loop *L) { 420*0b57cec5SDimitry Andric if (getBooleanLoopAttribute(L, "llvm.loop.licm_versioning.disable")) 421*0b57cec5SDimitry Andric return TM_SuppressedByUser; 422*0b57cec5SDimitry Andric 423*0b57cec5SDimitry Andric if (hasDisableAllTransformsHint(L)) 424*0b57cec5SDimitry Andric return TM_Disable; 425*0b57cec5SDimitry Andric 426*0b57cec5SDimitry Andric return TM_Unspecified; 427*0b57cec5SDimitry Andric } 428*0b57cec5SDimitry Andric 429*0b57cec5SDimitry Andric /// Does a BFS from a given node to all of its children inside a given loop. 430*0b57cec5SDimitry Andric /// The returned vector of nodes includes the starting point. 431*0b57cec5SDimitry Andric SmallVector<DomTreeNode *, 16> 432*0b57cec5SDimitry Andric llvm::collectChildrenInLoop(DomTreeNode *N, const Loop *CurLoop) { 433*0b57cec5SDimitry Andric SmallVector<DomTreeNode *, 16> Worklist; 434*0b57cec5SDimitry Andric auto AddRegionToWorklist = [&](DomTreeNode *DTN) { 435*0b57cec5SDimitry Andric // Only include subregions in the top level loop. 436*0b57cec5SDimitry Andric BasicBlock *BB = DTN->getBlock(); 437*0b57cec5SDimitry Andric if (CurLoop->contains(BB)) 438*0b57cec5SDimitry Andric Worklist.push_back(DTN); 439*0b57cec5SDimitry Andric }; 440*0b57cec5SDimitry Andric 441*0b57cec5SDimitry Andric AddRegionToWorklist(N); 442*0b57cec5SDimitry Andric 443*0b57cec5SDimitry Andric for (size_t I = 0; I < Worklist.size(); I++) 444*0b57cec5SDimitry Andric for (DomTreeNode *Child : Worklist[I]->getChildren()) 445*0b57cec5SDimitry Andric AddRegionToWorklist(Child); 446*0b57cec5SDimitry Andric 447*0b57cec5SDimitry Andric return Worklist; 448*0b57cec5SDimitry Andric } 449*0b57cec5SDimitry Andric 450*0b57cec5SDimitry Andric void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT = nullptr, 451*0b57cec5SDimitry Andric ScalarEvolution *SE = nullptr, 452*0b57cec5SDimitry Andric LoopInfo *LI = nullptr) { 453*0b57cec5SDimitry Andric assert((!DT || L->isLCSSAForm(*DT)) && "Expected LCSSA!"); 454*0b57cec5SDimitry Andric auto *Preheader = L->getLoopPreheader(); 455*0b57cec5SDimitry Andric assert(Preheader && "Preheader should exist!"); 456*0b57cec5SDimitry Andric 457*0b57cec5SDimitry Andric // Now that we know the removal is safe, remove the loop by changing the 458*0b57cec5SDimitry Andric // branch from the preheader to go to the single exit block. 459*0b57cec5SDimitry Andric // 460*0b57cec5SDimitry Andric // Because we're deleting a large chunk of code at once, the sequence in which 461*0b57cec5SDimitry Andric // we remove things is very important to avoid invalidation issues. 462*0b57cec5SDimitry Andric 463*0b57cec5SDimitry Andric // Tell ScalarEvolution that the loop is deleted. Do this before 464*0b57cec5SDimitry Andric // deleting the loop so that ScalarEvolution can look at the loop 465*0b57cec5SDimitry Andric // to determine what it needs to clean up. 466*0b57cec5SDimitry Andric if (SE) 467*0b57cec5SDimitry Andric SE->forgetLoop(L); 468*0b57cec5SDimitry Andric 469*0b57cec5SDimitry Andric auto *ExitBlock = L->getUniqueExitBlock(); 470*0b57cec5SDimitry Andric assert(ExitBlock && "Should have a unique exit block!"); 471*0b57cec5SDimitry Andric assert(L->hasDedicatedExits() && "Loop should have dedicated exits!"); 472*0b57cec5SDimitry Andric 473*0b57cec5SDimitry Andric auto *OldBr = dyn_cast<BranchInst>(Preheader->getTerminator()); 474*0b57cec5SDimitry Andric assert(OldBr && "Preheader must end with a branch"); 475*0b57cec5SDimitry Andric assert(OldBr->isUnconditional() && "Preheader must have a single successor"); 476*0b57cec5SDimitry Andric // Connect the preheader to the exit block. Keep the old edge to the header 477*0b57cec5SDimitry Andric // around to perform the dominator tree update in two separate steps 478*0b57cec5SDimitry Andric // -- #1 insertion of the edge preheader -> exit and #2 deletion of the edge 479*0b57cec5SDimitry Andric // preheader -> header. 480*0b57cec5SDimitry Andric // 481*0b57cec5SDimitry Andric // 482*0b57cec5SDimitry Andric // 0. Preheader 1. Preheader 2. Preheader 483*0b57cec5SDimitry Andric // | | | | 484*0b57cec5SDimitry Andric // V | V | 485*0b57cec5SDimitry Andric // Header <--\ | Header <--\ | Header <--\ 486*0b57cec5SDimitry Andric // | | | | | | | | | | | 487*0b57cec5SDimitry Andric // | V | | | V | | | V | 488*0b57cec5SDimitry Andric // | Body --/ | | Body --/ | | Body --/ 489*0b57cec5SDimitry Andric // V V V V V 490*0b57cec5SDimitry Andric // Exit Exit Exit 491*0b57cec5SDimitry Andric // 492*0b57cec5SDimitry Andric // By doing this is two separate steps we can perform the dominator tree 493*0b57cec5SDimitry Andric // update without using the batch update API. 494*0b57cec5SDimitry Andric // 495*0b57cec5SDimitry Andric // Even when the loop is never executed, we cannot remove the edge from the 496*0b57cec5SDimitry Andric // source block to the exit block. Consider the case where the unexecuted loop 497*0b57cec5SDimitry Andric // branches back to an outer loop. If we deleted the loop and removed the edge 498*0b57cec5SDimitry Andric // coming to this inner loop, this will break the outer loop structure (by 499*0b57cec5SDimitry Andric // deleting the backedge of the outer loop). If the outer loop is indeed a 500*0b57cec5SDimitry Andric // non-loop, it will be deleted in a future iteration of loop deletion pass. 501*0b57cec5SDimitry Andric IRBuilder<> Builder(OldBr); 502*0b57cec5SDimitry Andric Builder.CreateCondBr(Builder.getFalse(), L->getHeader(), ExitBlock); 503*0b57cec5SDimitry Andric // Remove the old branch. The conditional branch becomes a new terminator. 504*0b57cec5SDimitry Andric OldBr->eraseFromParent(); 505*0b57cec5SDimitry Andric 506*0b57cec5SDimitry Andric // Rewrite phis in the exit block to get their inputs from the Preheader 507*0b57cec5SDimitry Andric // instead of the exiting block. 508*0b57cec5SDimitry Andric for (PHINode &P : ExitBlock->phis()) { 509*0b57cec5SDimitry Andric // Set the zero'th element of Phi to be from the preheader and remove all 510*0b57cec5SDimitry Andric // other incoming values. Given the loop has dedicated exits, all other 511*0b57cec5SDimitry Andric // incoming values must be from the exiting blocks. 512*0b57cec5SDimitry Andric int PredIndex = 0; 513*0b57cec5SDimitry Andric P.setIncomingBlock(PredIndex, Preheader); 514*0b57cec5SDimitry Andric // Removes all incoming values from all other exiting blocks (including 515*0b57cec5SDimitry Andric // duplicate values from an exiting block). 516*0b57cec5SDimitry Andric // Nuke all entries except the zero'th entry which is the preheader entry. 517*0b57cec5SDimitry Andric // NOTE! We need to remove Incoming Values in the reverse order as done 518*0b57cec5SDimitry Andric // below, to keep the indices valid for deletion (removeIncomingValues 519*0b57cec5SDimitry Andric // updates getNumIncomingValues and shifts all values down into the operand 520*0b57cec5SDimitry Andric // being deleted). 521*0b57cec5SDimitry Andric for (unsigned i = 0, e = P.getNumIncomingValues() - 1; i != e; ++i) 522*0b57cec5SDimitry Andric P.removeIncomingValue(e - i, false); 523*0b57cec5SDimitry Andric 524*0b57cec5SDimitry Andric assert((P.getNumIncomingValues() == 1 && 525*0b57cec5SDimitry Andric P.getIncomingBlock(PredIndex) == Preheader) && 526*0b57cec5SDimitry Andric "Should have exactly one value and that's from the preheader!"); 527*0b57cec5SDimitry Andric } 528*0b57cec5SDimitry Andric 529*0b57cec5SDimitry Andric // Disconnect the loop body by branching directly to its exit. 530*0b57cec5SDimitry Andric Builder.SetInsertPoint(Preheader->getTerminator()); 531*0b57cec5SDimitry Andric Builder.CreateBr(ExitBlock); 532*0b57cec5SDimitry Andric // Remove the old branch. 533*0b57cec5SDimitry Andric Preheader->getTerminator()->eraseFromParent(); 534*0b57cec5SDimitry Andric 535*0b57cec5SDimitry Andric DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); 536*0b57cec5SDimitry Andric if (DT) { 537*0b57cec5SDimitry Andric // Update the dominator tree by informing it about the new edge from the 538*0b57cec5SDimitry Andric // preheader to the exit and the removed edge. 539*0b57cec5SDimitry Andric DTU.applyUpdates({{DominatorTree::Insert, Preheader, ExitBlock}, 540*0b57cec5SDimitry Andric {DominatorTree::Delete, Preheader, L->getHeader()}}); 541*0b57cec5SDimitry Andric } 542*0b57cec5SDimitry Andric 543*0b57cec5SDimitry Andric // Use a map to unique and a vector to guarantee deterministic ordering. 544*0b57cec5SDimitry Andric llvm::SmallDenseSet<std::pair<DIVariable *, DIExpression *>, 4> DeadDebugSet; 545*0b57cec5SDimitry Andric llvm::SmallVector<DbgVariableIntrinsic *, 4> DeadDebugInst; 546*0b57cec5SDimitry Andric 547*0b57cec5SDimitry Andric // Given LCSSA form is satisfied, we should not have users of instructions 548*0b57cec5SDimitry Andric // within the dead loop outside of the loop. However, LCSSA doesn't take 549*0b57cec5SDimitry Andric // unreachable uses into account. We handle them here. 550*0b57cec5SDimitry Andric // We could do it after drop all references (in this case all users in the 551*0b57cec5SDimitry Andric // loop will be already eliminated and we have less work to do but according 552*0b57cec5SDimitry Andric // to API doc of User::dropAllReferences only valid operation after dropping 553*0b57cec5SDimitry Andric // references, is deletion. So let's substitute all usages of 554*0b57cec5SDimitry Andric // instruction from the loop with undef value of corresponding type first. 555*0b57cec5SDimitry Andric for (auto *Block : L->blocks()) 556*0b57cec5SDimitry Andric for (Instruction &I : *Block) { 557*0b57cec5SDimitry Andric auto *Undef = UndefValue::get(I.getType()); 558*0b57cec5SDimitry Andric for (Value::use_iterator UI = I.use_begin(), E = I.use_end(); UI != E;) { 559*0b57cec5SDimitry Andric Use &U = *UI; 560*0b57cec5SDimitry Andric ++UI; 561*0b57cec5SDimitry Andric if (auto *Usr = dyn_cast<Instruction>(U.getUser())) 562*0b57cec5SDimitry Andric if (L->contains(Usr->getParent())) 563*0b57cec5SDimitry Andric continue; 564*0b57cec5SDimitry Andric // If we have a DT then we can check that uses outside a loop only in 565*0b57cec5SDimitry Andric // unreachable block. 566*0b57cec5SDimitry Andric if (DT) 567*0b57cec5SDimitry Andric assert(!DT->isReachableFromEntry(U) && 568*0b57cec5SDimitry Andric "Unexpected user in reachable block"); 569*0b57cec5SDimitry Andric U.set(Undef); 570*0b57cec5SDimitry Andric } 571*0b57cec5SDimitry Andric auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I); 572*0b57cec5SDimitry Andric if (!DVI) 573*0b57cec5SDimitry Andric continue; 574*0b57cec5SDimitry Andric auto Key = DeadDebugSet.find({DVI->getVariable(), DVI->getExpression()}); 575*0b57cec5SDimitry Andric if (Key != DeadDebugSet.end()) 576*0b57cec5SDimitry Andric continue; 577*0b57cec5SDimitry Andric DeadDebugSet.insert({DVI->getVariable(), DVI->getExpression()}); 578*0b57cec5SDimitry Andric DeadDebugInst.push_back(DVI); 579*0b57cec5SDimitry Andric } 580*0b57cec5SDimitry Andric 581*0b57cec5SDimitry Andric // After the loop has been deleted all the values defined and modified 582*0b57cec5SDimitry Andric // inside the loop are going to be unavailable. 583*0b57cec5SDimitry Andric // Since debug values in the loop have been deleted, inserting an undef 584*0b57cec5SDimitry Andric // dbg.value truncates the range of any dbg.value before the loop where the 585*0b57cec5SDimitry Andric // loop used to be. This is particularly important for constant values. 586*0b57cec5SDimitry Andric DIBuilder DIB(*ExitBlock->getModule()); 587*0b57cec5SDimitry Andric Instruction *InsertDbgValueBefore = ExitBlock->getFirstNonPHI(); 588*0b57cec5SDimitry Andric assert(InsertDbgValueBefore && 589*0b57cec5SDimitry Andric "There should be a non-PHI instruction in exit block, else these " 590*0b57cec5SDimitry Andric "instructions will have no parent."); 591*0b57cec5SDimitry Andric for (auto *DVI : DeadDebugInst) 592*0b57cec5SDimitry Andric DIB.insertDbgValueIntrinsic(UndefValue::get(Builder.getInt32Ty()), 593*0b57cec5SDimitry Andric DVI->getVariable(), DVI->getExpression(), 594*0b57cec5SDimitry Andric DVI->getDebugLoc(), InsertDbgValueBefore); 595*0b57cec5SDimitry Andric 596*0b57cec5SDimitry Andric // Remove the block from the reference counting scheme, so that we can 597*0b57cec5SDimitry Andric // delete it freely later. 598*0b57cec5SDimitry Andric for (auto *Block : L->blocks()) 599*0b57cec5SDimitry Andric Block->dropAllReferences(); 600*0b57cec5SDimitry Andric 601*0b57cec5SDimitry Andric if (LI) { 602*0b57cec5SDimitry Andric // Erase the instructions and the blocks without having to worry 603*0b57cec5SDimitry Andric // about ordering because we already dropped the references. 604*0b57cec5SDimitry Andric // NOTE: This iteration is safe because erasing the block does not remove 605*0b57cec5SDimitry Andric // its entry from the loop's block list. We do that in the next section. 606*0b57cec5SDimitry Andric for (Loop::block_iterator LpI = L->block_begin(), LpE = L->block_end(); 607*0b57cec5SDimitry Andric LpI != LpE; ++LpI) 608*0b57cec5SDimitry Andric (*LpI)->eraseFromParent(); 609*0b57cec5SDimitry Andric 610*0b57cec5SDimitry Andric // Finally, the blocks from loopinfo. This has to happen late because 611*0b57cec5SDimitry Andric // otherwise our loop iterators won't work. 612*0b57cec5SDimitry Andric 613*0b57cec5SDimitry Andric SmallPtrSet<BasicBlock *, 8> blocks; 614*0b57cec5SDimitry Andric blocks.insert(L->block_begin(), L->block_end()); 615*0b57cec5SDimitry Andric for (BasicBlock *BB : blocks) 616*0b57cec5SDimitry Andric LI->removeBlock(BB); 617*0b57cec5SDimitry Andric 618*0b57cec5SDimitry Andric // The last step is to update LoopInfo now that we've eliminated this loop. 619*0b57cec5SDimitry Andric LI->erase(L); 620*0b57cec5SDimitry Andric } 621*0b57cec5SDimitry Andric } 622*0b57cec5SDimitry Andric 623*0b57cec5SDimitry Andric Optional<unsigned> llvm::getLoopEstimatedTripCount(Loop *L) { 624*0b57cec5SDimitry Andric // Support loops with an exiting latch and other existing exists only 625*0b57cec5SDimitry Andric // deoptimize. 626*0b57cec5SDimitry Andric 627*0b57cec5SDimitry Andric // Get the branch weights for the loop's backedge. 628*0b57cec5SDimitry Andric BasicBlock *Latch = L->getLoopLatch(); 629*0b57cec5SDimitry Andric if (!Latch) 630*0b57cec5SDimitry Andric return None; 631*0b57cec5SDimitry Andric BranchInst *LatchBR = dyn_cast<BranchInst>(Latch->getTerminator()); 632*0b57cec5SDimitry Andric if (!LatchBR || LatchBR->getNumSuccessors() != 2 || !L->isLoopExiting(Latch)) 633*0b57cec5SDimitry Andric return None; 634*0b57cec5SDimitry Andric 635*0b57cec5SDimitry Andric assert((LatchBR->getSuccessor(0) == L->getHeader() || 636*0b57cec5SDimitry Andric LatchBR->getSuccessor(1) == L->getHeader()) && 637*0b57cec5SDimitry Andric "At least one edge out of the latch must go to the header"); 638*0b57cec5SDimitry Andric 639*0b57cec5SDimitry Andric SmallVector<BasicBlock *, 4> ExitBlocks; 640*0b57cec5SDimitry Andric L->getUniqueNonLatchExitBlocks(ExitBlocks); 641*0b57cec5SDimitry Andric if (any_of(ExitBlocks, [](const BasicBlock *EB) { 642*0b57cec5SDimitry Andric return !EB->getTerminatingDeoptimizeCall(); 643*0b57cec5SDimitry Andric })) 644*0b57cec5SDimitry Andric return None; 645*0b57cec5SDimitry Andric 646*0b57cec5SDimitry Andric // To estimate the number of times the loop body was executed, we want to 647*0b57cec5SDimitry Andric // know the number of times the backedge was taken, vs. the number of times 648*0b57cec5SDimitry Andric // we exited the loop. 649*0b57cec5SDimitry Andric uint64_t TrueVal, FalseVal; 650*0b57cec5SDimitry Andric if (!LatchBR->extractProfMetadata(TrueVal, FalseVal)) 651*0b57cec5SDimitry Andric return None; 652*0b57cec5SDimitry Andric 653*0b57cec5SDimitry Andric if (!TrueVal || !FalseVal) 654*0b57cec5SDimitry Andric return 0; 655*0b57cec5SDimitry Andric 656*0b57cec5SDimitry Andric // Divide the count of the backedge by the count of the edge exiting the loop, 657*0b57cec5SDimitry Andric // rounding to nearest. 658*0b57cec5SDimitry Andric if (LatchBR->getSuccessor(0) == L->getHeader()) 659*0b57cec5SDimitry Andric return (TrueVal + (FalseVal / 2)) / FalseVal; 660*0b57cec5SDimitry Andric else 661*0b57cec5SDimitry Andric return (FalseVal + (TrueVal / 2)) / TrueVal; 662*0b57cec5SDimitry Andric } 663*0b57cec5SDimitry Andric 664*0b57cec5SDimitry Andric bool llvm::hasIterationCountInvariantInParent(Loop *InnerLoop, 665*0b57cec5SDimitry Andric ScalarEvolution &SE) { 666*0b57cec5SDimitry Andric Loop *OuterL = InnerLoop->getParentLoop(); 667*0b57cec5SDimitry Andric if (!OuterL) 668*0b57cec5SDimitry Andric return true; 669*0b57cec5SDimitry Andric 670*0b57cec5SDimitry Andric // Get the backedge taken count for the inner loop 671*0b57cec5SDimitry Andric BasicBlock *InnerLoopLatch = InnerLoop->getLoopLatch(); 672*0b57cec5SDimitry Andric const SCEV *InnerLoopBECountSC = SE.getExitCount(InnerLoop, InnerLoopLatch); 673*0b57cec5SDimitry Andric if (isa<SCEVCouldNotCompute>(InnerLoopBECountSC) || 674*0b57cec5SDimitry Andric !InnerLoopBECountSC->getType()->isIntegerTy()) 675*0b57cec5SDimitry Andric return false; 676*0b57cec5SDimitry Andric 677*0b57cec5SDimitry Andric // Get whether count is invariant to the outer loop 678*0b57cec5SDimitry Andric ScalarEvolution::LoopDisposition LD = 679*0b57cec5SDimitry Andric SE.getLoopDisposition(InnerLoopBECountSC, OuterL); 680*0b57cec5SDimitry Andric if (LD != ScalarEvolution::LoopInvariant) 681*0b57cec5SDimitry Andric return false; 682*0b57cec5SDimitry Andric 683*0b57cec5SDimitry Andric return true; 684*0b57cec5SDimitry Andric } 685*0b57cec5SDimitry Andric 686*0b57cec5SDimitry Andric Value *llvm::createMinMaxOp(IRBuilder<> &Builder, 687*0b57cec5SDimitry Andric RecurrenceDescriptor::MinMaxRecurrenceKind RK, 688*0b57cec5SDimitry Andric Value *Left, Value *Right) { 689*0b57cec5SDimitry Andric CmpInst::Predicate P = CmpInst::ICMP_NE; 690*0b57cec5SDimitry Andric switch (RK) { 691*0b57cec5SDimitry Andric default: 692*0b57cec5SDimitry Andric llvm_unreachable("Unknown min/max recurrence kind"); 693*0b57cec5SDimitry Andric case RecurrenceDescriptor::MRK_UIntMin: 694*0b57cec5SDimitry Andric P = CmpInst::ICMP_ULT; 695*0b57cec5SDimitry Andric break; 696*0b57cec5SDimitry Andric case RecurrenceDescriptor::MRK_UIntMax: 697*0b57cec5SDimitry Andric P = CmpInst::ICMP_UGT; 698*0b57cec5SDimitry Andric break; 699*0b57cec5SDimitry Andric case RecurrenceDescriptor::MRK_SIntMin: 700*0b57cec5SDimitry Andric P = CmpInst::ICMP_SLT; 701*0b57cec5SDimitry Andric break; 702*0b57cec5SDimitry Andric case RecurrenceDescriptor::MRK_SIntMax: 703*0b57cec5SDimitry Andric P = CmpInst::ICMP_SGT; 704*0b57cec5SDimitry Andric break; 705*0b57cec5SDimitry Andric case RecurrenceDescriptor::MRK_FloatMin: 706*0b57cec5SDimitry Andric P = CmpInst::FCMP_OLT; 707*0b57cec5SDimitry Andric break; 708*0b57cec5SDimitry Andric case RecurrenceDescriptor::MRK_FloatMax: 709*0b57cec5SDimitry Andric P = CmpInst::FCMP_OGT; 710*0b57cec5SDimitry Andric break; 711*0b57cec5SDimitry Andric } 712*0b57cec5SDimitry Andric 713*0b57cec5SDimitry Andric // We only match FP sequences that are 'fast', so we can unconditionally 714*0b57cec5SDimitry Andric // set it on any generated instructions. 715*0b57cec5SDimitry Andric IRBuilder<>::FastMathFlagGuard FMFG(Builder); 716*0b57cec5SDimitry Andric FastMathFlags FMF; 717*0b57cec5SDimitry Andric FMF.setFast(); 718*0b57cec5SDimitry Andric Builder.setFastMathFlags(FMF); 719*0b57cec5SDimitry Andric 720*0b57cec5SDimitry Andric Value *Cmp; 721*0b57cec5SDimitry Andric if (RK == RecurrenceDescriptor::MRK_FloatMin || 722*0b57cec5SDimitry Andric RK == RecurrenceDescriptor::MRK_FloatMax) 723*0b57cec5SDimitry Andric Cmp = Builder.CreateFCmp(P, Left, Right, "rdx.minmax.cmp"); 724*0b57cec5SDimitry Andric else 725*0b57cec5SDimitry Andric Cmp = Builder.CreateICmp(P, Left, Right, "rdx.minmax.cmp"); 726*0b57cec5SDimitry Andric 727*0b57cec5SDimitry Andric Value *Select = Builder.CreateSelect(Cmp, Left, Right, "rdx.minmax.select"); 728*0b57cec5SDimitry Andric return Select; 729*0b57cec5SDimitry Andric } 730*0b57cec5SDimitry Andric 731*0b57cec5SDimitry Andric // Helper to generate an ordered reduction. 732*0b57cec5SDimitry Andric Value * 733*0b57cec5SDimitry Andric llvm::getOrderedReduction(IRBuilder<> &Builder, Value *Acc, Value *Src, 734*0b57cec5SDimitry Andric unsigned Op, 735*0b57cec5SDimitry Andric RecurrenceDescriptor::MinMaxRecurrenceKind MinMaxKind, 736*0b57cec5SDimitry Andric ArrayRef<Value *> RedOps) { 737*0b57cec5SDimitry Andric unsigned VF = Src->getType()->getVectorNumElements(); 738*0b57cec5SDimitry Andric 739*0b57cec5SDimitry Andric // Extract and apply reduction ops in ascending order: 740*0b57cec5SDimitry Andric // e.g. ((((Acc + Scl[0]) + Scl[1]) + Scl[2]) + ) ... + Scl[VF-1] 741*0b57cec5SDimitry Andric Value *Result = Acc; 742*0b57cec5SDimitry Andric for (unsigned ExtractIdx = 0; ExtractIdx != VF; ++ExtractIdx) { 743*0b57cec5SDimitry Andric Value *Ext = 744*0b57cec5SDimitry Andric Builder.CreateExtractElement(Src, Builder.getInt32(ExtractIdx)); 745*0b57cec5SDimitry Andric 746*0b57cec5SDimitry Andric if (Op != Instruction::ICmp && Op != Instruction::FCmp) { 747*0b57cec5SDimitry Andric Result = Builder.CreateBinOp((Instruction::BinaryOps)Op, Result, Ext, 748*0b57cec5SDimitry Andric "bin.rdx"); 749*0b57cec5SDimitry Andric } else { 750*0b57cec5SDimitry Andric assert(MinMaxKind != RecurrenceDescriptor::MRK_Invalid && 751*0b57cec5SDimitry Andric "Invalid min/max"); 752*0b57cec5SDimitry Andric Result = createMinMaxOp(Builder, MinMaxKind, Result, Ext); 753*0b57cec5SDimitry Andric } 754*0b57cec5SDimitry Andric 755*0b57cec5SDimitry Andric if (!RedOps.empty()) 756*0b57cec5SDimitry Andric propagateIRFlags(Result, RedOps); 757*0b57cec5SDimitry Andric } 758*0b57cec5SDimitry Andric 759*0b57cec5SDimitry Andric return Result; 760*0b57cec5SDimitry Andric } 761*0b57cec5SDimitry Andric 762*0b57cec5SDimitry Andric // Helper to generate a log2 shuffle reduction. 763*0b57cec5SDimitry Andric Value * 764*0b57cec5SDimitry Andric llvm::getShuffleReduction(IRBuilder<> &Builder, Value *Src, unsigned Op, 765*0b57cec5SDimitry Andric RecurrenceDescriptor::MinMaxRecurrenceKind MinMaxKind, 766*0b57cec5SDimitry Andric ArrayRef<Value *> RedOps) { 767*0b57cec5SDimitry Andric unsigned VF = Src->getType()->getVectorNumElements(); 768*0b57cec5SDimitry Andric // VF is a power of 2 so we can emit the reduction using log2(VF) shuffles 769*0b57cec5SDimitry Andric // and vector ops, reducing the set of values being computed by half each 770*0b57cec5SDimitry Andric // round. 771*0b57cec5SDimitry Andric assert(isPowerOf2_32(VF) && 772*0b57cec5SDimitry Andric "Reduction emission only supported for pow2 vectors!"); 773*0b57cec5SDimitry Andric Value *TmpVec = Src; 774*0b57cec5SDimitry Andric SmallVector<Constant *, 32> ShuffleMask(VF, nullptr); 775*0b57cec5SDimitry Andric for (unsigned i = VF; i != 1; i >>= 1) { 776*0b57cec5SDimitry Andric // Move the upper half of the vector to the lower half. 777*0b57cec5SDimitry Andric for (unsigned j = 0; j != i / 2; ++j) 778*0b57cec5SDimitry Andric ShuffleMask[j] = Builder.getInt32(i / 2 + j); 779*0b57cec5SDimitry Andric 780*0b57cec5SDimitry Andric // Fill the rest of the mask with undef. 781*0b57cec5SDimitry Andric std::fill(&ShuffleMask[i / 2], ShuffleMask.end(), 782*0b57cec5SDimitry Andric UndefValue::get(Builder.getInt32Ty())); 783*0b57cec5SDimitry Andric 784*0b57cec5SDimitry Andric Value *Shuf = Builder.CreateShuffleVector( 785*0b57cec5SDimitry Andric TmpVec, UndefValue::get(TmpVec->getType()), 786*0b57cec5SDimitry Andric ConstantVector::get(ShuffleMask), "rdx.shuf"); 787*0b57cec5SDimitry Andric 788*0b57cec5SDimitry Andric if (Op != Instruction::ICmp && Op != Instruction::FCmp) { 789*0b57cec5SDimitry Andric // The builder propagates its fast-math-flags setting. 790*0b57cec5SDimitry Andric TmpVec = Builder.CreateBinOp((Instruction::BinaryOps)Op, TmpVec, Shuf, 791*0b57cec5SDimitry Andric "bin.rdx"); 792*0b57cec5SDimitry Andric } else { 793*0b57cec5SDimitry Andric assert(MinMaxKind != RecurrenceDescriptor::MRK_Invalid && 794*0b57cec5SDimitry Andric "Invalid min/max"); 795*0b57cec5SDimitry Andric TmpVec = createMinMaxOp(Builder, MinMaxKind, TmpVec, Shuf); 796*0b57cec5SDimitry Andric } 797*0b57cec5SDimitry Andric if (!RedOps.empty()) 798*0b57cec5SDimitry Andric propagateIRFlags(TmpVec, RedOps); 799*0b57cec5SDimitry Andric } 800*0b57cec5SDimitry Andric // The result is in the first element of the vector. 801*0b57cec5SDimitry Andric return Builder.CreateExtractElement(TmpVec, Builder.getInt32(0)); 802*0b57cec5SDimitry Andric } 803*0b57cec5SDimitry Andric 804*0b57cec5SDimitry Andric /// Create a simple vector reduction specified by an opcode and some 805*0b57cec5SDimitry Andric /// flags (if generating min/max reductions). 806*0b57cec5SDimitry Andric Value *llvm::createSimpleTargetReduction( 807*0b57cec5SDimitry Andric IRBuilder<> &Builder, const TargetTransformInfo *TTI, unsigned Opcode, 808*0b57cec5SDimitry Andric Value *Src, TargetTransformInfo::ReductionFlags Flags, 809*0b57cec5SDimitry Andric ArrayRef<Value *> RedOps) { 810*0b57cec5SDimitry Andric assert(isa<VectorType>(Src->getType()) && "Type must be a vector"); 811*0b57cec5SDimitry Andric 812*0b57cec5SDimitry Andric std::function<Value *()> BuildFunc; 813*0b57cec5SDimitry Andric using RD = RecurrenceDescriptor; 814*0b57cec5SDimitry Andric RD::MinMaxRecurrenceKind MinMaxKind = RD::MRK_Invalid; 815*0b57cec5SDimitry Andric 816*0b57cec5SDimitry Andric switch (Opcode) { 817*0b57cec5SDimitry Andric case Instruction::Add: 818*0b57cec5SDimitry Andric BuildFunc = [&]() { return Builder.CreateAddReduce(Src); }; 819*0b57cec5SDimitry Andric break; 820*0b57cec5SDimitry Andric case Instruction::Mul: 821*0b57cec5SDimitry Andric BuildFunc = [&]() { return Builder.CreateMulReduce(Src); }; 822*0b57cec5SDimitry Andric break; 823*0b57cec5SDimitry Andric case Instruction::And: 824*0b57cec5SDimitry Andric BuildFunc = [&]() { return Builder.CreateAndReduce(Src); }; 825*0b57cec5SDimitry Andric break; 826*0b57cec5SDimitry Andric case Instruction::Or: 827*0b57cec5SDimitry Andric BuildFunc = [&]() { return Builder.CreateOrReduce(Src); }; 828*0b57cec5SDimitry Andric break; 829*0b57cec5SDimitry Andric case Instruction::Xor: 830*0b57cec5SDimitry Andric BuildFunc = [&]() { return Builder.CreateXorReduce(Src); }; 831*0b57cec5SDimitry Andric break; 832*0b57cec5SDimitry Andric case Instruction::FAdd: 833*0b57cec5SDimitry Andric BuildFunc = [&]() { 834*0b57cec5SDimitry Andric auto Rdx = Builder.CreateFAddReduce( 835*0b57cec5SDimitry Andric Constant::getNullValue(Src->getType()->getVectorElementType()), Src); 836*0b57cec5SDimitry Andric return Rdx; 837*0b57cec5SDimitry Andric }; 838*0b57cec5SDimitry Andric break; 839*0b57cec5SDimitry Andric case Instruction::FMul: 840*0b57cec5SDimitry Andric BuildFunc = [&]() { 841*0b57cec5SDimitry Andric Type *Ty = Src->getType()->getVectorElementType(); 842*0b57cec5SDimitry Andric auto Rdx = Builder.CreateFMulReduce(ConstantFP::get(Ty, 1.0), Src); 843*0b57cec5SDimitry Andric return Rdx; 844*0b57cec5SDimitry Andric }; 845*0b57cec5SDimitry Andric break; 846*0b57cec5SDimitry Andric case Instruction::ICmp: 847*0b57cec5SDimitry Andric if (Flags.IsMaxOp) { 848*0b57cec5SDimitry Andric MinMaxKind = Flags.IsSigned ? RD::MRK_SIntMax : RD::MRK_UIntMax; 849*0b57cec5SDimitry Andric BuildFunc = [&]() { 850*0b57cec5SDimitry Andric return Builder.CreateIntMaxReduce(Src, Flags.IsSigned); 851*0b57cec5SDimitry Andric }; 852*0b57cec5SDimitry Andric } else { 853*0b57cec5SDimitry Andric MinMaxKind = Flags.IsSigned ? RD::MRK_SIntMin : RD::MRK_UIntMin; 854*0b57cec5SDimitry Andric BuildFunc = [&]() { 855*0b57cec5SDimitry Andric return Builder.CreateIntMinReduce(Src, Flags.IsSigned); 856*0b57cec5SDimitry Andric }; 857*0b57cec5SDimitry Andric } 858*0b57cec5SDimitry Andric break; 859*0b57cec5SDimitry Andric case Instruction::FCmp: 860*0b57cec5SDimitry Andric if (Flags.IsMaxOp) { 861*0b57cec5SDimitry Andric MinMaxKind = RD::MRK_FloatMax; 862*0b57cec5SDimitry Andric BuildFunc = [&]() { return Builder.CreateFPMaxReduce(Src, Flags.NoNaN); }; 863*0b57cec5SDimitry Andric } else { 864*0b57cec5SDimitry Andric MinMaxKind = RD::MRK_FloatMin; 865*0b57cec5SDimitry Andric BuildFunc = [&]() { return Builder.CreateFPMinReduce(Src, Flags.NoNaN); }; 866*0b57cec5SDimitry Andric } 867*0b57cec5SDimitry Andric break; 868*0b57cec5SDimitry Andric default: 869*0b57cec5SDimitry Andric llvm_unreachable("Unhandled opcode"); 870*0b57cec5SDimitry Andric break; 871*0b57cec5SDimitry Andric } 872*0b57cec5SDimitry Andric if (TTI->useReductionIntrinsic(Opcode, Src->getType(), Flags)) 873*0b57cec5SDimitry Andric return BuildFunc(); 874*0b57cec5SDimitry Andric return getShuffleReduction(Builder, Src, Opcode, MinMaxKind, RedOps); 875*0b57cec5SDimitry Andric } 876*0b57cec5SDimitry Andric 877*0b57cec5SDimitry Andric /// Create a vector reduction using a given recurrence descriptor. 878*0b57cec5SDimitry Andric Value *llvm::createTargetReduction(IRBuilder<> &B, 879*0b57cec5SDimitry Andric const TargetTransformInfo *TTI, 880*0b57cec5SDimitry Andric RecurrenceDescriptor &Desc, Value *Src, 881*0b57cec5SDimitry Andric bool NoNaN) { 882*0b57cec5SDimitry Andric // TODO: Support in-order reductions based on the recurrence descriptor. 883*0b57cec5SDimitry Andric using RD = RecurrenceDescriptor; 884*0b57cec5SDimitry Andric RD::RecurrenceKind RecKind = Desc.getRecurrenceKind(); 885*0b57cec5SDimitry Andric TargetTransformInfo::ReductionFlags Flags; 886*0b57cec5SDimitry Andric Flags.NoNaN = NoNaN; 887*0b57cec5SDimitry Andric 888*0b57cec5SDimitry Andric // All ops in the reduction inherit fast-math-flags from the recurrence 889*0b57cec5SDimitry Andric // descriptor. 890*0b57cec5SDimitry Andric IRBuilder<>::FastMathFlagGuard FMFGuard(B); 891*0b57cec5SDimitry Andric B.setFastMathFlags(Desc.getFastMathFlags()); 892*0b57cec5SDimitry Andric 893*0b57cec5SDimitry Andric switch (RecKind) { 894*0b57cec5SDimitry Andric case RD::RK_FloatAdd: 895*0b57cec5SDimitry Andric return createSimpleTargetReduction(B, TTI, Instruction::FAdd, Src, Flags); 896*0b57cec5SDimitry Andric case RD::RK_FloatMult: 897*0b57cec5SDimitry Andric return createSimpleTargetReduction(B, TTI, Instruction::FMul, Src, Flags); 898*0b57cec5SDimitry Andric case RD::RK_IntegerAdd: 899*0b57cec5SDimitry Andric return createSimpleTargetReduction(B, TTI, Instruction::Add, Src, Flags); 900*0b57cec5SDimitry Andric case RD::RK_IntegerMult: 901*0b57cec5SDimitry Andric return createSimpleTargetReduction(B, TTI, Instruction::Mul, Src, Flags); 902*0b57cec5SDimitry Andric case RD::RK_IntegerAnd: 903*0b57cec5SDimitry Andric return createSimpleTargetReduction(B, TTI, Instruction::And, Src, Flags); 904*0b57cec5SDimitry Andric case RD::RK_IntegerOr: 905*0b57cec5SDimitry Andric return createSimpleTargetReduction(B, TTI, Instruction::Or, Src, Flags); 906*0b57cec5SDimitry Andric case RD::RK_IntegerXor: 907*0b57cec5SDimitry Andric return createSimpleTargetReduction(B, TTI, Instruction::Xor, Src, Flags); 908*0b57cec5SDimitry Andric case RD::RK_IntegerMinMax: { 909*0b57cec5SDimitry Andric RD::MinMaxRecurrenceKind MMKind = Desc.getMinMaxRecurrenceKind(); 910*0b57cec5SDimitry Andric Flags.IsMaxOp = (MMKind == RD::MRK_SIntMax || MMKind == RD::MRK_UIntMax); 911*0b57cec5SDimitry Andric Flags.IsSigned = (MMKind == RD::MRK_SIntMax || MMKind == RD::MRK_SIntMin); 912*0b57cec5SDimitry Andric return createSimpleTargetReduction(B, TTI, Instruction::ICmp, Src, Flags); 913*0b57cec5SDimitry Andric } 914*0b57cec5SDimitry Andric case RD::RK_FloatMinMax: { 915*0b57cec5SDimitry Andric Flags.IsMaxOp = Desc.getMinMaxRecurrenceKind() == RD::MRK_FloatMax; 916*0b57cec5SDimitry Andric return createSimpleTargetReduction(B, TTI, Instruction::FCmp, Src, Flags); 917*0b57cec5SDimitry Andric } 918*0b57cec5SDimitry Andric default: 919*0b57cec5SDimitry Andric llvm_unreachable("Unhandled RecKind"); 920*0b57cec5SDimitry Andric } 921*0b57cec5SDimitry Andric } 922*0b57cec5SDimitry Andric 923*0b57cec5SDimitry Andric void llvm::propagateIRFlags(Value *I, ArrayRef<Value *> VL, Value *OpValue) { 924*0b57cec5SDimitry Andric auto *VecOp = dyn_cast<Instruction>(I); 925*0b57cec5SDimitry Andric if (!VecOp) 926*0b57cec5SDimitry Andric return; 927*0b57cec5SDimitry Andric auto *Intersection = (OpValue == nullptr) ? dyn_cast<Instruction>(VL[0]) 928*0b57cec5SDimitry Andric : dyn_cast<Instruction>(OpValue); 929*0b57cec5SDimitry Andric if (!Intersection) 930*0b57cec5SDimitry Andric return; 931*0b57cec5SDimitry Andric const unsigned Opcode = Intersection->getOpcode(); 932*0b57cec5SDimitry Andric VecOp->copyIRFlags(Intersection); 933*0b57cec5SDimitry Andric for (auto *V : VL) { 934*0b57cec5SDimitry Andric auto *Instr = dyn_cast<Instruction>(V); 935*0b57cec5SDimitry Andric if (!Instr) 936*0b57cec5SDimitry Andric continue; 937*0b57cec5SDimitry Andric if (OpValue == nullptr || Opcode == Instr->getOpcode()) 938*0b57cec5SDimitry Andric VecOp->andIRFlags(V); 939*0b57cec5SDimitry Andric } 940*0b57cec5SDimitry Andric } 941*0b57cec5SDimitry Andric 942*0b57cec5SDimitry Andric bool llvm::isKnownNegativeInLoop(const SCEV *S, const Loop *L, 943*0b57cec5SDimitry Andric ScalarEvolution &SE) { 944*0b57cec5SDimitry Andric const SCEV *Zero = SE.getZero(S->getType()); 945*0b57cec5SDimitry Andric return SE.isAvailableAtLoopEntry(S, L) && 946*0b57cec5SDimitry Andric SE.isLoopEntryGuardedByCond(L, ICmpInst::ICMP_SLT, S, Zero); 947*0b57cec5SDimitry Andric } 948*0b57cec5SDimitry Andric 949*0b57cec5SDimitry Andric bool llvm::isKnownNonNegativeInLoop(const SCEV *S, const Loop *L, 950*0b57cec5SDimitry Andric ScalarEvolution &SE) { 951*0b57cec5SDimitry Andric const SCEV *Zero = SE.getZero(S->getType()); 952*0b57cec5SDimitry Andric return SE.isAvailableAtLoopEntry(S, L) && 953*0b57cec5SDimitry Andric SE.isLoopEntryGuardedByCond(L, ICmpInst::ICMP_SGE, S, Zero); 954*0b57cec5SDimitry Andric } 955*0b57cec5SDimitry Andric 956*0b57cec5SDimitry Andric bool llvm::cannotBeMinInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE, 957*0b57cec5SDimitry Andric bool Signed) { 958*0b57cec5SDimitry Andric unsigned BitWidth = cast<IntegerType>(S->getType())->getBitWidth(); 959*0b57cec5SDimitry Andric APInt Min = Signed ? APInt::getSignedMinValue(BitWidth) : 960*0b57cec5SDimitry Andric APInt::getMinValue(BitWidth); 961*0b57cec5SDimitry Andric auto Predicate = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; 962*0b57cec5SDimitry Andric return SE.isAvailableAtLoopEntry(S, L) && 963*0b57cec5SDimitry Andric SE.isLoopEntryGuardedByCond(L, Predicate, S, 964*0b57cec5SDimitry Andric SE.getConstant(Min)); 965*0b57cec5SDimitry Andric } 966*0b57cec5SDimitry Andric 967*0b57cec5SDimitry Andric bool llvm::cannotBeMaxInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE, 968*0b57cec5SDimitry Andric bool Signed) { 969*0b57cec5SDimitry Andric unsigned BitWidth = cast<IntegerType>(S->getType())->getBitWidth(); 970*0b57cec5SDimitry Andric APInt Max = Signed ? APInt::getSignedMaxValue(BitWidth) : 971*0b57cec5SDimitry Andric APInt::getMaxValue(BitWidth); 972*0b57cec5SDimitry Andric auto Predicate = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; 973*0b57cec5SDimitry Andric return SE.isAvailableAtLoopEntry(S, L) && 974*0b57cec5SDimitry Andric SE.isLoopEntryGuardedByCond(L, Predicate, S, 975*0b57cec5SDimitry Andric SE.getConstant(Max)); 976*0b57cec5SDimitry Andric } 977