176aa662cSKarthik Bhat //===-- LoopUtils.cpp - Loop Utility functions -------------------------===// 276aa662cSKarthik Bhat // 376aa662cSKarthik Bhat // The LLVM Compiler Infrastructure 476aa662cSKarthik Bhat // 576aa662cSKarthik Bhat // This file is distributed under the University of Illinois Open Source 676aa662cSKarthik Bhat // License. See LICENSE.TXT for details. 776aa662cSKarthik Bhat // 876aa662cSKarthik Bhat //===----------------------------------------------------------------------===// 976aa662cSKarthik Bhat // 1076aa662cSKarthik Bhat // This file defines common loop utility functions. 1176aa662cSKarthik Bhat // 1276aa662cSKarthik Bhat //===----------------------------------------------------------------------===// 1376aa662cSKarthik Bhat 1476aa662cSKarthik Bhat #include "llvm/Analysis/LoopInfo.h" 1576aa662cSKarthik Bhat #include "llvm/IR/Instructions.h" 1676aa662cSKarthik Bhat #include "llvm/IR/PatternMatch.h" 1776aa662cSKarthik Bhat #include "llvm/IR/ValueHandle.h" 1876aa662cSKarthik Bhat #include "llvm/Support/Debug.h" 1924e6cc2dSKarthik Bhat #include "llvm/Analysis/ScalarEvolution.h" 2024e6cc2dSKarthik Bhat #include "llvm/Analysis/ScalarEvolutionExpressions.h" 2124e6cc2dSKarthik Bhat #include "llvm/IR/Module.h" 2276aa662cSKarthik Bhat #include "llvm/Transforms/Utils/LoopUtils.h" 2376aa662cSKarthik Bhat 2476aa662cSKarthik Bhat using namespace llvm; 2576aa662cSKarthik Bhat using namespace llvm::PatternMatch; 2676aa662cSKarthik Bhat 2776aa662cSKarthik Bhat #define DEBUG_TYPE "loop-utils" 2876aa662cSKarthik Bhat 290a91310cSTyler Nowicki bool RecurrenceDescriptor::areAllUsesIn(Instruction *I, 3076aa662cSKarthik Bhat SmallPtrSetImpl<Instruction *> &Set) { 3176aa662cSKarthik Bhat for (User::op_iterator Use = I->op_begin(), E = I->op_end(); Use != E; ++Use) 3276aa662cSKarthik Bhat if (!Set.count(dyn_cast<Instruction>(*Use))) 3376aa662cSKarthik Bhat return false; 3476aa662cSKarthik Bhat return true; 3576aa662cSKarthik Bhat } 3676aa662cSKarthik Bhat 370a91310cSTyler Nowicki bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurrenceKind Kind, 3876aa662cSKarthik Bhat Loop *TheLoop, bool HasFunNoNaNAttr, 390a91310cSTyler Nowicki RecurrenceDescriptor &RedDes) { 4076aa662cSKarthik Bhat if (Phi->getNumIncomingValues() != 2) 4176aa662cSKarthik Bhat return false; 4276aa662cSKarthik Bhat 4376aa662cSKarthik Bhat // Reduction variables are only found in the loop header block. 4476aa662cSKarthik Bhat if (Phi->getParent() != TheLoop->getHeader()) 4576aa662cSKarthik Bhat return false; 4676aa662cSKarthik Bhat 4776aa662cSKarthik Bhat // Obtain the reduction start value from the value that comes from the loop 4876aa662cSKarthik Bhat // preheader. 4976aa662cSKarthik Bhat Value *RdxStart = Phi->getIncomingValueForBlock(TheLoop->getLoopPreheader()); 5076aa662cSKarthik Bhat 5176aa662cSKarthik Bhat // ExitInstruction is the single value which is used outside the loop. 5276aa662cSKarthik Bhat // We only allow for a single reduction value to be used outside the loop. 5376aa662cSKarthik Bhat // This includes users of the reduction, variables (which form a cycle 5476aa662cSKarthik Bhat // which ends in the phi node). 5576aa662cSKarthik Bhat Instruction *ExitInstruction = nullptr; 5676aa662cSKarthik Bhat // Indicates that we found a reduction operation in our scan. 5776aa662cSKarthik Bhat bool FoundReduxOp = false; 5876aa662cSKarthik Bhat 5976aa662cSKarthik Bhat // We start with the PHI node and scan for all of the users of this 6076aa662cSKarthik Bhat // instruction. All users must be instructions that can be used as reduction 6176aa662cSKarthik Bhat // variables (such as ADD). We must have a single out-of-block user. The cycle 6276aa662cSKarthik Bhat // must include the original PHI. 6376aa662cSKarthik Bhat bool FoundStartPHI = false; 6476aa662cSKarthik Bhat 6576aa662cSKarthik Bhat // To recognize min/max patterns formed by a icmp select sequence, we store 6676aa662cSKarthik Bhat // the number of instruction we saw from the recognized min/max pattern, 6776aa662cSKarthik Bhat // to make sure we only see exactly the two instructions. 6876aa662cSKarthik Bhat unsigned NumCmpSelectPatternInst = 0; 6927b2c39eSTyler Nowicki InstDesc ReduxDesc(false, nullptr); 7076aa662cSKarthik Bhat 7176aa662cSKarthik Bhat SmallPtrSet<Instruction *, 8> VisitedInsts; 7276aa662cSKarthik Bhat SmallVector<Instruction *, 8> Worklist; 7376aa662cSKarthik Bhat Worklist.push_back(Phi); 7476aa662cSKarthik Bhat VisitedInsts.insert(Phi); 7576aa662cSKarthik Bhat 7676aa662cSKarthik Bhat // A value in the reduction can be used: 7776aa662cSKarthik Bhat // - By the reduction: 7876aa662cSKarthik Bhat // - Reduction operation: 7976aa662cSKarthik Bhat // - One use of reduction value (safe). 8076aa662cSKarthik Bhat // - Multiple use of reduction value (not safe). 8176aa662cSKarthik Bhat // - PHI: 8276aa662cSKarthik Bhat // - All uses of the PHI must be the reduction (safe). 8376aa662cSKarthik Bhat // - Otherwise, not safe. 8476aa662cSKarthik Bhat // - By one instruction outside of the loop (safe). 8576aa662cSKarthik Bhat // - By further instructions outside of the loop (not safe). 8676aa662cSKarthik Bhat // - By an instruction that is not part of the reduction (not safe). 8776aa662cSKarthik Bhat // This is either: 8876aa662cSKarthik Bhat // * An instruction type other than PHI or the reduction operation. 8976aa662cSKarthik Bhat // * A PHI in the header other than the initial PHI. 9076aa662cSKarthik Bhat while (!Worklist.empty()) { 9176aa662cSKarthik Bhat Instruction *Cur = Worklist.back(); 9276aa662cSKarthik Bhat Worklist.pop_back(); 9376aa662cSKarthik Bhat 9476aa662cSKarthik Bhat // No Users. 9576aa662cSKarthik Bhat // If the instruction has no users then this is a broken chain and can't be 9676aa662cSKarthik Bhat // a reduction variable. 9776aa662cSKarthik Bhat if (Cur->use_empty()) 9876aa662cSKarthik Bhat return false; 9976aa662cSKarthik Bhat 10076aa662cSKarthik Bhat bool IsAPhi = isa<PHINode>(Cur); 10176aa662cSKarthik Bhat 10276aa662cSKarthik Bhat // A header PHI use other than the original PHI. 10376aa662cSKarthik Bhat if (Cur != Phi && IsAPhi && Cur->getParent() == Phi->getParent()) 10476aa662cSKarthik Bhat return false; 10576aa662cSKarthik Bhat 10676aa662cSKarthik Bhat // Reductions of instructions such as Div, and Sub is only possible if the 10776aa662cSKarthik Bhat // LHS is the reduction variable. 10876aa662cSKarthik Bhat if (!Cur->isCommutative() && !IsAPhi && !isa<SelectInst>(Cur) && 10976aa662cSKarthik Bhat !isa<ICmpInst>(Cur) && !isa<FCmpInst>(Cur) && 11076aa662cSKarthik Bhat !VisitedInsts.count(dyn_cast<Instruction>(Cur->getOperand(0)))) 11176aa662cSKarthik Bhat return false; 11276aa662cSKarthik Bhat 11376aa662cSKarthik Bhat // Any reduction instruction must be of one of the allowed kinds. 1140a91310cSTyler Nowicki ReduxDesc = isRecurrenceInstr(Cur, Kind, ReduxDesc, HasFunNoNaNAttr); 1150a91310cSTyler Nowicki if (!ReduxDesc.isRecurrence()) 11676aa662cSKarthik Bhat return false; 11776aa662cSKarthik Bhat 11876aa662cSKarthik Bhat // A reduction operation must only have one use of the reduction value. 11976aa662cSKarthik Bhat if (!IsAPhi && Kind != RK_IntegerMinMax && Kind != RK_FloatMinMax && 12076aa662cSKarthik Bhat hasMultipleUsesOf(Cur, VisitedInsts)) 12176aa662cSKarthik Bhat return false; 12276aa662cSKarthik Bhat 12376aa662cSKarthik Bhat // All inputs to a PHI node must be a reduction value. 12476aa662cSKarthik Bhat if (IsAPhi && Cur != Phi && !areAllUsesIn(Cur, VisitedInsts)) 12576aa662cSKarthik Bhat return false; 12676aa662cSKarthik Bhat 12776aa662cSKarthik Bhat if (Kind == RK_IntegerMinMax && 12876aa662cSKarthik Bhat (isa<ICmpInst>(Cur) || isa<SelectInst>(Cur))) 12976aa662cSKarthik Bhat ++NumCmpSelectPatternInst; 13076aa662cSKarthik Bhat if (Kind == RK_FloatMinMax && (isa<FCmpInst>(Cur) || isa<SelectInst>(Cur))) 13176aa662cSKarthik Bhat ++NumCmpSelectPatternInst; 13276aa662cSKarthik Bhat 13376aa662cSKarthik Bhat // Check whether we found a reduction operator. 13476aa662cSKarthik Bhat FoundReduxOp |= !IsAPhi; 13576aa662cSKarthik Bhat 13676aa662cSKarthik Bhat // Process users of current instruction. Push non-PHI nodes after PHI nodes 13776aa662cSKarthik Bhat // onto the stack. This way we are going to have seen all inputs to PHI 13876aa662cSKarthik Bhat // nodes once we get to them. 13976aa662cSKarthik Bhat SmallVector<Instruction *, 8> NonPHIs; 14076aa662cSKarthik Bhat SmallVector<Instruction *, 8> PHIs; 14176aa662cSKarthik Bhat for (User *U : Cur->users()) { 14276aa662cSKarthik Bhat Instruction *UI = cast<Instruction>(U); 14376aa662cSKarthik Bhat 14476aa662cSKarthik Bhat // Check if we found the exit user. 14576aa662cSKarthik Bhat BasicBlock *Parent = UI->getParent(); 14676aa662cSKarthik Bhat if (!TheLoop->contains(Parent)) { 14776aa662cSKarthik Bhat // Exit if you find multiple outside users or if the header phi node is 14876aa662cSKarthik Bhat // being used. In this case the user uses the value of the previous 14976aa662cSKarthik Bhat // iteration, in which case we would loose "VF-1" iterations of the 15076aa662cSKarthik Bhat // reduction operation if we vectorize. 15176aa662cSKarthik Bhat if (ExitInstruction != nullptr || Cur == Phi) 15276aa662cSKarthik Bhat return false; 15376aa662cSKarthik Bhat 15476aa662cSKarthik Bhat // The instruction used by an outside user must be the last instruction 15576aa662cSKarthik Bhat // before we feed back to the reduction phi. Otherwise, we loose VF-1 15676aa662cSKarthik Bhat // operations on the value. 15776aa662cSKarthik Bhat if (std::find(Phi->op_begin(), Phi->op_end(), Cur) == Phi->op_end()) 15876aa662cSKarthik Bhat return false; 15976aa662cSKarthik Bhat 16076aa662cSKarthik Bhat ExitInstruction = Cur; 16176aa662cSKarthik Bhat continue; 16276aa662cSKarthik Bhat } 16376aa662cSKarthik Bhat 16476aa662cSKarthik Bhat // Process instructions only once (termination). Each reduction cycle 16576aa662cSKarthik Bhat // value must only be used once, except by phi nodes and min/max 16676aa662cSKarthik Bhat // reductions which are represented as a cmp followed by a select. 16727b2c39eSTyler Nowicki InstDesc IgnoredVal(false, nullptr); 16876aa662cSKarthik Bhat if (VisitedInsts.insert(UI).second) { 16976aa662cSKarthik Bhat if (isa<PHINode>(UI)) 17076aa662cSKarthik Bhat PHIs.push_back(UI); 17176aa662cSKarthik Bhat else 17276aa662cSKarthik Bhat NonPHIs.push_back(UI); 17376aa662cSKarthik Bhat } else if (!isa<PHINode>(UI) && 17476aa662cSKarthik Bhat ((!isa<FCmpInst>(UI) && !isa<ICmpInst>(UI) && 17576aa662cSKarthik Bhat !isa<SelectInst>(UI)) || 1760a91310cSTyler Nowicki !isMinMaxSelectCmpPattern(UI, IgnoredVal).isRecurrence())) 17776aa662cSKarthik Bhat return false; 17876aa662cSKarthik Bhat 17976aa662cSKarthik Bhat // Remember that we completed the cycle. 18076aa662cSKarthik Bhat if (UI == Phi) 18176aa662cSKarthik Bhat FoundStartPHI = true; 18276aa662cSKarthik Bhat } 18376aa662cSKarthik Bhat Worklist.append(PHIs.begin(), PHIs.end()); 18476aa662cSKarthik Bhat Worklist.append(NonPHIs.begin(), NonPHIs.end()); 18576aa662cSKarthik Bhat } 18676aa662cSKarthik Bhat 18776aa662cSKarthik Bhat // This means we have seen one but not the other instruction of the 18876aa662cSKarthik Bhat // pattern or more than just a select and cmp. 18976aa662cSKarthik Bhat if ((Kind == RK_IntegerMinMax || Kind == RK_FloatMinMax) && 19076aa662cSKarthik Bhat NumCmpSelectPatternInst != 2) 19176aa662cSKarthik Bhat return false; 19276aa662cSKarthik Bhat 19376aa662cSKarthik Bhat if (!FoundStartPHI || !FoundReduxOp || !ExitInstruction) 19476aa662cSKarthik Bhat return false; 19576aa662cSKarthik Bhat 19676aa662cSKarthik Bhat // We found a reduction var if we have reached the original phi node and we 19776aa662cSKarthik Bhat // only have a single instruction with out-of-loop users. 19876aa662cSKarthik Bhat 19976aa662cSKarthik Bhat // The ExitInstruction(Instruction which is allowed to have out-of-loop users) 2000a91310cSTyler Nowicki // is saved as part of the RecurrenceDescriptor. 20176aa662cSKarthik Bhat 20276aa662cSKarthik Bhat // Save the description of this reduction variable. 2030a91310cSTyler Nowicki RecurrenceDescriptor RD(RdxStart, ExitInstruction, Kind, 204c1a86f58STyler Nowicki ReduxDesc.getMinMaxKind(), 205c1a86f58STyler Nowicki ReduxDesc.getUnsafeAlgebraInst()); 20676aa662cSKarthik Bhat 20776aa662cSKarthik Bhat RedDes = RD; 20876aa662cSKarthik Bhat 20976aa662cSKarthik Bhat return true; 21076aa662cSKarthik Bhat } 21176aa662cSKarthik Bhat 21276aa662cSKarthik Bhat /// Returns true if the instruction is a Select(ICmp(X, Y), X, Y) instruction 21376aa662cSKarthik Bhat /// pattern corresponding to a min(X, Y) or max(X, Y). 21427b2c39eSTyler Nowicki RecurrenceDescriptor::InstDesc 21527b2c39eSTyler Nowicki RecurrenceDescriptor::isMinMaxSelectCmpPattern(Instruction *I, InstDesc &Prev) { 21676aa662cSKarthik Bhat 21776aa662cSKarthik Bhat assert((isa<ICmpInst>(I) || isa<FCmpInst>(I) || isa<SelectInst>(I)) && 21876aa662cSKarthik Bhat "Expect a select instruction"); 21976aa662cSKarthik Bhat Instruction *Cmp = nullptr; 22076aa662cSKarthik Bhat SelectInst *Select = nullptr; 22176aa662cSKarthik Bhat 22276aa662cSKarthik Bhat // We must handle the select(cmp()) as a single instruction. Advance to the 22376aa662cSKarthik Bhat // select. 22476aa662cSKarthik Bhat if ((Cmp = dyn_cast<ICmpInst>(I)) || (Cmp = dyn_cast<FCmpInst>(I))) { 22576aa662cSKarthik Bhat if (!Cmp->hasOneUse() || !(Select = dyn_cast<SelectInst>(*I->user_begin()))) 22627b2c39eSTyler Nowicki return InstDesc(false, I); 22727b2c39eSTyler Nowicki return InstDesc(Select, Prev.getMinMaxKind()); 22876aa662cSKarthik Bhat } 22976aa662cSKarthik Bhat 23076aa662cSKarthik Bhat // Only handle single use cases for now. 23176aa662cSKarthik Bhat if (!(Select = dyn_cast<SelectInst>(I))) 23227b2c39eSTyler Nowicki return InstDesc(false, I); 23376aa662cSKarthik Bhat if (!(Cmp = dyn_cast<ICmpInst>(I->getOperand(0))) && 23476aa662cSKarthik Bhat !(Cmp = dyn_cast<FCmpInst>(I->getOperand(0)))) 23527b2c39eSTyler Nowicki return InstDesc(false, I); 23676aa662cSKarthik Bhat if (!Cmp->hasOneUse()) 23727b2c39eSTyler Nowicki return InstDesc(false, I); 23876aa662cSKarthik Bhat 23976aa662cSKarthik Bhat Value *CmpLeft; 24076aa662cSKarthik Bhat Value *CmpRight; 24176aa662cSKarthik Bhat 24276aa662cSKarthik Bhat // Look for a min/max pattern. 24376aa662cSKarthik Bhat if (m_UMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 24427b2c39eSTyler Nowicki return InstDesc(Select, MRK_UIntMin); 24576aa662cSKarthik Bhat else if (m_UMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 24627b2c39eSTyler Nowicki return InstDesc(Select, MRK_UIntMax); 24776aa662cSKarthik Bhat else if (m_SMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 24827b2c39eSTyler Nowicki return InstDesc(Select, MRK_SIntMax); 24976aa662cSKarthik Bhat else if (m_SMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 25027b2c39eSTyler Nowicki return InstDesc(Select, MRK_SIntMin); 25176aa662cSKarthik Bhat else if (m_OrdFMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 25227b2c39eSTyler Nowicki return InstDesc(Select, MRK_FloatMin); 25376aa662cSKarthik Bhat else if (m_OrdFMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 25427b2c39eSTyler Nowicki return InstDesc(Select, MRK_FloatMax); 25576aa662cSKarthik Bhat else if (m_UnordFMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 25627b2c39eSTyler Nowicki return InstDesc(Select, MRK_FloatMin); 25776aa662cSKarthik Bhat else if (m_UnordFMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 25827b2c39eSTyler Nowicki return InstDesc(Select, MRK_FloatMax); 25976aa662cSKarthik Bhat 26027b2c39eSTyler Nowicki return InstDesc(false, I); 26176aa662cSKarthik Bhat } 26276aa662cSKarthik Bhat 26327b2c39eSTyler Nowicki RecurrenceDescriptor::InstDesc 2640a91310cSTyler Nowicki RecurrenceDescriptor::isRecurrenceInstr(Instruction *I, RecurrenceKind Kind, 26527b2c39eSTyler Nowicki InstDesc &Prev, bool HasFunNoNaNAttr) { 26676aa662cSKarthik Bhat bool FP = I->getType()->isFloatingPointTy(); 267c1a86f58STyler Nowicki Instruction *UAI = Prev.getUnsafeAlgebraInst(); 268c1a86f58STyler Nowicki if (!UAI && FP && !I->hasUnsafeAlgebra()) 269c1a86f58STyler Nowicki UAI = I; // Found an unsafe (unvectorizable) algebra instruction. 270c1a86f58STyler Nowicki 27176aa662cSKarthik Bhat switch (I->getOpcode()) { 27276aa662cSKarthik Bhat default: 27327b2c39eSTyler Nowicki return InstDesc(false, I); 27476aa662cSKarthik Bhat case Instruction::PHI: 27576aa662cSKarthik Bhat if (FP && 27676aa662cSKarthik Bhat (Kind != RK_FloatMult && Kind != RK_FloatAdd && Kind != RK_FloatMinMax)) 27727b2c39eSTyler Nowicki return InstDesc(false, I); 27827b2c39eSTyler Nowicki return InstDesc(I, Prev.getMinMaxKind()); 27976aa662cSKarthik Bhat case Instruction::Sub: 28076aa662cSKarthik Bhat case Instruction::Add: 28127b2c39eSTyler Nowicki return InstDesc(Kind == RK_IntegerAdd, I); 28276aa662cSKarthik Bhat case Instruction::Mul: 28327b2c39eSTyler Nowicki return InstDesc(Kind == RK_IntegerMult, I); 28476aa662cSKarthik Bhat case Instruction::And: 28527b2c39eSTyler Nowicki return InstDesc(Kind == RK_IntegerAnd, I); 28676aa662cSKarthik Bhat case Instruction::Or: 28727b2c39eSTyler Nowicki return InstDesc(Kind == RK_IntegerOr, I); 28876aa662cSKarthik Bhat case Instruction::Xor: 28927b2c39eSTyler Nowicki return InstDesc(Kind == RK_IntegerXor, I); 29076aa662cSKarthik Bhat case Instruction::FMul: 291c1a86f58STyler Nowicki return InstDesc(Kind == RK_FloatMult, I, UAI); 29276aa662cSKarthik Bhat case Instruction::FSub: 29376aa662cSKarthik Bhat case Instruction::FAdd: 294c1a86f58STyler Nowicki return InstDesc(Kind == RK_FloatAdd, I, UAI); 29576aa662cSKarthik Bhat case Instruction::FCmp: 29676aa662cSKarthik Bhat case Instruction::ICmp: 29776aa662cSKarthik Bhat case Instruction::Select: 29876aa662cSKarthik Bhat if (Kind != RK_IntegerMinMax && 29976aa662cSKarthik Bhat (!HasFunNoNaNAttr || Kind != RK_FloatMinMax)) 30027b2c39eSTyler Nowicki return InstDesc(false, I); 30176aa662cSKarthik Bhat return isMinMaxSelectCmpPattern(I, Prev); 30276aa662cSKarthik Bhat } 30376aa662cSKarthik Bhat } 30476aa662cSKarthik Bhat 3050a91310cSTyler Nowicki bool RecurrenceDescriptor::hasMultipleUsesOf( 30676aa662cSKarthik Bhat Instruction *I, SmallPtrSetImpl<Instruction *> &Insts) { 30776aa662cSKarthik Bhat unsigned NumUses = 0; 30876aa662cSKarthik Bhat for (User::op_iterator Use = I->op_begin(), E = I->op_end(); Use != E; 30976aa662cSKarthik Bhat ++Use) { 31076aa662cSKarthik Bhat if (Insts.count(dyn_cast<Instruction>(*Use))) 31176aa662cSKarthik Bhat ++NumUses; 31276aa662cSKarthik Bhat if (NumUses > 1) 31376aa662cSKarthik Bhat return true; 31476aa662cSKarthik Bhat } 31576aa662cSKarthik Bhat 31676aa662cSKarthik Bhat return false; 31776aa662cSKarthik Bhat } 3180a91310cSTyler Nowicki bool RecurrenceDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop, 3190a91310cSTyler Nowicki RecurrenceDescriptor &RedDes) { 32076aa662cSKarthik Bhat 32176aa662cSKarthik Bhat bool HasFunNoNaNAttr = false; 32276aa662cSKarthik Bhat BasicBlock *Header = TheLoop->getHeader(); 32376aa662cSKarthik Bhat Function &F = *Header->getParent(); 32476aa662cSKarthik Bhat if (F.hasFnAttribute("no-nans-fp-math")) 32576aa662cSKarthik Bhat HasFunNoNaNAttr = 32676aa662cSKarthik Bhat F.getFnAttribute("no-nans-fp-math").getValueAsString() == "true"; 32776aa662cSKarthik Bhat 32876aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_IntegerAdd, TheLoop, HasFunNoNaNAttr, RedDes)) { 32976aa662cSKarthik Bhat DEBUG(dbgs() << "Found an ADD reduction PHI." << *Phi << "\n"); 33076aa662cSKarthik Bhat return true; 33176aa662cSKarthik Bhat } 33276aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_IntegerMult, TheLoop, HasFunNoNaNAttr, RedDes)) { 33376aa662cSKarthik Bhat DEBUG(dbgs() << "Found a MUL reduction PHI." << *Phi << "\n"); 33476aa662cSKarthik Bhat return true; 33576aa662cSKarthik Bhat } 33676aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_IntegerOr, TheLoop, HasFunNoNaNAttr, RedDes)) { 33776aa662cSKarthik Bhat DEBUG(dbgs() << "Found an OR reduction PHI." << *Phi << "\n"); 33876aa662cSKarthik Bhat return true; 33976aa662cSKarthik Bhat } 34076aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_IntegerAnd, TheLoop, HasFunNoNaNAttr, RedDes)) { 34176aa662cSKarthik Bhat DEBUG(dbgs() << "Found an AND reduction PHI." << *Phi << "\n"); 34276aa662cSKarthik Bhat return true; 34376aa662cSKarthik Bhat } 34476aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_IntegerXor, TheLoop, HasFunNoNaNAttr, RedDes)) { 34576aa662cSKarthik Bhat DEBUG(dbgs() << "Found a XOR reduction PHI." << *Phi << "\n"); 34676aa662cSKarthik Bhat return true; 34776aa662cSKarthik Bhat } 34876aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_IntegerMinMax, TheLoop, HasFunNoNaNAttr, 34976aa662cSKarthik Bhat RedDes)) { 35076aa662cSKarthik Bhat DEBUG(dbgs() << "Found a MINMAX reduction PHI." << *Phi << "\n"); 35176aa662cSKarthik Bhat return true; 35276aa662cSKarthik Bhat } 35376aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_FloatMult, TheLoop, HasFunNoNaNAttr, RedDes)) { 35476aa662cSKarthik Bhat DEBUG(dbgs() << "Found an FMult reduction PHI." << *Phi << "\n"); 35576aa662cSKarthik Bhat return true; 35676aa662cSKarthik Bhat } 35776aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_FloatAdd, TheLoop, HasFunNoNaNAttr, RedDes)) { 35876aa662cSKarthik Bhat DEBUG(dbgs() << "Found an FAdd reduction PHI." << *Phi << "\n"); 35976aa662cSKarthik Bhat return true; 36076aa662cSKarthik Bhat } 36176aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_FloatMinMax, TheLoop, HasFunNoNaNAttr, RedDes)) { 36276aa662cSKarthik Bhat DEBUG(dbgs() << "Found an float MINMAX reduction PHI." << *Phi << "\n"); 36376aa662cSKarthik Bhat return true; 36476aa662cSKarthik Bhat } 36576aa662cSKarthik Bhat // Not a reduction of known type. 36676aa662cSKarthik Bhat return false; 36776aa662cSKarthik Bhat } 36876aa662cSKarthik Bhat 36976aa662cSKarthik Bhat /// This function returns the identity element (or neutral element) for 37076aa662cSKarthik Bhat /// the operation K. 3710a91310cSTyler Nowicki Constant *RecurrenceDescriptor::getRecurrenceIdentity(RecurrenceKind K, 3720a91310cSTyler Nowicki Type *Tp) { 37376aa662cSKarthik Bhat switch (K) { 37476aa662cSKarthik Bhat case RK_IntegerXor: 37576aa662cSKarthik Bhat case RK_IntegerAdd: 37676aa662cSKarthik Bhat case RK_IntegerOr: 37776aa662cSKarthik Bhat // Adding, Xoring, Oring zero to a number does not change it. 37876aa662cSKarthik Bhat return ConstantInt::get(Tp, 0); 37976aa662cSKarthik Bhat case RK_IntegerMult: 38076aa662cSKarthik Bhat // Multiplying a number by 1 does not change it. 38176aa662cSKarthik Bhat return ConstantInt::get(Tp, 1); 38276aa662cSKarthik Bhat case RK_IntegerAnd: 38376aa662cSKarthik Bhat // AND-ing a number with an all-1 value does not change it. 38476aa662cSKarthik Bhat return ConstantInt::get(Tp, -1, true); 38576aa662cSKarthik Bhat case RK_FloatMult: 38676aa662cSKarthik Bhat // Multiplying a number by 1 does not change it. 38776aa662cSKarthik Bhat return ConstantFP::get(Tp, 1.0L); 38876aa662cSKarthik Bhat case RK_FloatAdd: 38976aa662cSKarthik Bhat // Adding zero to a number does not change it. 39076aa662cSKarthik Bhat return ConstantFP::get(Tp, 0.0L); 39176aa662cSKarthik Bhat default: 3920a91310cSTyler Nowicki llvm_unreachable("Unknown recurrence kind"); 39376aa662cSKarthik Bhat } 39476aa662cSKarthik Bhat } 39576aa662cSKarthik Bhat 3960a91310cSTyler Nowicki /// This function translates the recurrence kind to an LLVM binary operator. 3970a91310cSTyler Nowicki unsigned RecurrenceDescriptor::getRecurrenceBinOp(RecurrenceKind Kind) { 39876aa662cSKarthik Bhat switch (Kind) { 39976aa662cSKarthik Bhat case RK_IntegerAdd: 40076aa662cSKarthik Bhat return Instruction::Add; 40176aa662cSKarthik Bhat case RK_IntegerMult: 40276aa662cSKarthik Bhat return Instruction::Mul; 40376aa662cSKarthik Bhat case RK_IntegerOr: 40476aa662cSKarthik Bhat return Instruction::Or; 40576aa662cSKarthik Bhat case RK_IntegerAnd: 40676aa662cSKarthik Bhat return Instruction::And; 40776aa662cSKarthik Bhat case RK_IntegerXor: 40876aa662cSKarthik Bhat return Instruction::Xor; 40976aa662cSKarthik Bhat case RK_FloatMult: 41076aa662cSKarthik Bhat return Instruction::FMul; 41176aa662cSKarthik Bhat case RK_FloatAdd: 41276aa662cSKarthik Bhat return Instruction::FAdd; 41376aa662cSKarthik Bhat case RK_IntegerMinMax: 41476aa662cSKarthik Bhat return Instruction::ICmp; 41576aa662cSKarthik Bhat case RK_FloatMinMax: 41676aa662cSKarthik Bhat return Instruction::FCmp; 41776aa662cSKarthik Bhat default: 4180a91310cSTyler Nowicki llvm_unreachable("Unknown recurrence operation"); 41976aa662cSKarthik Bhat } 42076aa662cSKarthik Bhat } 42176aa662cSKarthik Bhat 42227b2c39eSTyler Nowicki Value *RecurrenceDescriptor::createMinMaxOp(IRBuilder<> &Builder, 42327b2c39eSTyler Nowicki MinMaxRecurrenceKind RK, 42476aa662cSKarthik Bhat Value *Left, Value *Right) { 42576aa662cSKarthik Bhat CmpInst::Predicate P = CmpInst::ICMP_NE; 42676aa662cSKarthik Bhat switch (RK) { 42776aa662cSKarthik Bhat default: 4280a91310cSTyler Nowicki llvm_unreachable("Unknown min/max recurrence kind"); 42927b2c39eSTyler Nowicki case MRK_UIntMin: 43076aa662cSKarthik Bhat P = CmpInst::ICMP_ULT; 43176aa662cSKarthik Bhat break; 43227b2c39eSTyler Nowicki case MRK_UIntMax: 43376aa662cSKarthik Bhat P = CmpInst::ICMP_UGT; 43476aa662cSKarthik Bhat break; 43527b2c39eSTyler Nowicki case MRK_SIntMin: 43676aa662cSKarthik Bhat P = CmpInst::ICMP_SLT; 43776aa662cSKarthik Bhat break; 43827b2c39eSTyler Nowicki case MRK_SIntMax: 43976aa662cSKarthik Bhat P = CmpInst::ICMP_SGT; 44076aa662cSKarthik Bhat break; 44127b2c39eSTyler Nowicki case MRK_FloatMin: 44276aa662cSKarthik Bhat P = CmpInst::FCMP_OLT; 44376aa662cSKarthik Bhat break; 44427b2c39eSTyler Nowicki case MRK_FloatMax: 44576aa662cSKarthik Bhat P = CmpInst::FCMP_OGT; 44676aa662cSKarthik Bhat break; 44776aa662cSKarthik Bhat } 44876aa662cSKarthik Bhat 44976aa662cSKarthik Bhat Value *Cmp; 45027b2c39eSTyler Nowicki if (RK == MRK_FloatMin || RK == MRK_FloatMax) 45176aa662cSKarthik Bhat Cmp = Builder.CreateFCmp(P, Left, Right, "rdx.minmax.cmp"); 45276aa662cSKarthik Bhat else 45376aa662cSKarthik Bhat Cmp = Builder.CreateICmp(P, Left, Right, "rdx.minmax.cmp"); 45476aa662cSKarthik Bhat 45576aa662cSKarthik Bhat Value *Select = Builder.CreateSelect(Cmp, Left, Right, "rdx.minmax.select"); 45676aa662cSKarthik Bhat return Select; 45776aa662cSKarthik Bhat } 45824e6cc2dSKarthik Bhat 459*1bbf15c5SJames Molloy InductionDescriptor::InductionDescriptor(Value *Start, InductionKind K, 460*1bbf15c5SJames Molloy ConstantInt *Step) 461*1bbf15c5SJames Molloy : StartValue(Start), IK(K), StepValue(Step) { 462*1bbf15c5SJames Molloy assert(IK != IK_NoInduction && "Not an induction"); 463*1bbf15c5SJames Molloy assert(StartValue && "StartValue is null"); 464*1bbf15c5SJames Molloy assert(StepValue && !StepValue->isZero() && "StepValue is zero"); 465*1bbf15c5SJames Molloy assert((IK != IK_PtrInduction || StartValue->getType()->isPointerTy()) && 466*1bbf15c5SJames Molloy "StartValue is not a pointer for pointer induction"); 467*1bbf15c5SJames Molloy assert((IK != IK_IntInduction || StartValue->getType()->isIntegerTy()) && 468*1bbf15c5SJames Molloy "StartValue is not an integer for integer induction"); 469*1bbf15c5SJames Molloy assert(StepValue->getType()->isIntegerTy() && 470*1bbf15c5SJames Molloy "StepValue is not an integer"); 471*1bbf15c5SJames Molloy } 472*1bbf15c5SJames Molloy 473*1bbf15c5SJames Molloy int InductionDescriptor::getConsecutiveDirection() const { 474*1bbf15c5SJames Molloy if (StepValue && (StepValue->isOne() || StepValue->isMinusOne())) 475*1bbf15c5SJames Molloy return StepValue->getSExtValue(); 476*1bbf15c5SJames Molloy return 0; 477*1bbf15c5SJames Molloy } 478*1bbf15c5SJames Molloy 479*1bbf15c5SJames Molloy Value *InductionDescriptor::transform(IRBuilder<> &B, Value *Index) const { 480*1bbf15c5SJames Molloy switch (IK) { 481*1bbf15c5SJames Molloy case IK_IntInduction: 482*1bbf15c5SJames Molloy assert(Index->getType() == StartValue->getType() && 483*1bbf15c5SJames Molloy "Index type does not match StartValue type"); 484*1bbf15c5SJames Molloy if (StepValue->isMinusOne()) 485*1bbf15c5SJames Molloy return B.CreateSub(StartValue, Index); 486*1bbf15c5SJames Molloy if (!StepValue->isOne()) 487*1bbf15c5SJames Molloy Index = B.CreateMul(Index, StepValue); 488*1bbf15c5SJames Molloy return B.CreateAdd(StartValue, Index); 489*1bbf15c5SJames Molloy 490*1bbf15c5SJames Molloy case IK_PtrInduction: 491*1bbf15c5SJames Molloy assert(Index->getType() == StepValue->getType() && 492*1bbf15c5SJames Molloy "Index type does not match StepValue type"); 493*1bbf15c5SJames Molloy if (StepValue->isMinusOne()) 494*1bbf15c5SJames Molloy Index = B.CreateNeg(Index); 495*1bbf15c5SJames Molloy else if (!StepValue->isOne()) 496*1bbf15c5SJames Molloy Index = B.CreateMul(Index, StepValue); 497*1bbf15c5SJames Molloy return B.CreateGEP(nullptr, StartValue, Index); 498*1bbf15c5SJames Molloy 499*1bbf15c5SJames Molloy case IK_NoInduction: 500*1bbf15c5SJames Molloy return nullptr; 501*1bbf15c5SJames Molloy } 502*1bbf15c5SJames Molloy llvm_unreachable("invalid enum"); 503*1bbf15c5SJames Molloy } 504*1bbf15c5SJames Molloy 505*1bbf15c5SJames Molloy bool InductionDescriptor::isInductionPHI(PHINode *Phi, ScalarEvolution *SE, 506*1bbf15c5SJames Molloy InductionDescriptor &D) { 50724e6cc2dSKarthik Bhat Type *PhiTy = Phi->getType(); 50824e6cc2dSKarthik Bhat // We only handle integer and pointer inductions variables. 50924e6cc2dSKarthik Bhat if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy()) 51024e6cc2dSKarthik Bhat return false; 51124e6cc2dSKarthik Bhat 51224e6cc2dSKarthik Bhat // Check that the PHI is consecutive. 51324e6cc2dSKarthik Bhat const SCEV *PhiScev = SE->getSCEV(Phi); 51424e6cc2dSKarthik Bhat const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PhiScev); 51524e6cc2dSKarthik Bhat if (!AR) { 51624e6cc2dSKarthik Bhat DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n"); 51724e6cc2dSKarthik Bhat return false; 51824e6cc2dSKarthik Bhat } 51924e6cc2dSKarthik Bhat 520*1bbf15c5SJames Molloy assert(AR->getLoop()->getHeader() == Phi->getParent() && 521*1bbf15c5SJames Molloy "PHI is an AddRec for a different loop?!"); 522*1bbf15c5SJames Molloy Value *StartValue = 523*1bbf15c5SJames Molloy Phi->getIncomingValueForBlock(AR->getLoop()->getLoopPreheader()); 52424e6cc2dSKarthik Bhat const SCEV *Step = AR->getStepRecurrence(*SE); 52524e6cc2dSKarthik Bhat // Calculate the pointer stride and check if it is consecutive. 52624e6cc2dSKarthik Bhat const SCEVConstant *C = dyn_cast<SCEVConstant>(Step); 52724e6cc2dSKarthik Bhat if (!C) 52824e6cc2dSKarthik Bhat return false; 52924e6cc2dSKarthik Bhat 53024e6cc2dSKarthik Bhat ConstantInt *CV = C->getValue(); 53124e6cc2dSKarthik Bhat if (PhiTy->isIntegerTy()) { 532*1bbf15c5SJames Molloy D = InductionDescriptor(StartValue, IK_IntInduction, CV); 53324e6cc2dSKarthik Bhat return true; 53424e6cc2dSKarthik Bhat } 53524e6cc2dSKarthik Bhat 53624e6cc2dSKarthik Bhat assert(PhiTy->isPointerTy() && "The PHI must be a pointer"); 53724e6cc2dSKarthik Bhat Type *PointerElementType = PhiTy->getPointerElementType(); 53824e6cc2dSKarthik Bhat // The pointer stride cannot be determined if the pointer element type is not 53924e6cc2dSKarthik Bhat // sized. 54024e6cc2dSKarthik Bhat if (!PointerElementType->isSized()) 54124e6cc2dSKarthik Bhat return false; 54224e6cc2dSKarthik Bhat 54324e6cc2dSKarthik Bhat const DataLayout &DL = Phi->getModule()->getDataLayout(); 54424e6cc2dSKarthik Bhat int64_t Size = static_cast<int64_t>(DL.getTypeAllocSize(PointerElementType)); 545b58f32f7SDavid Majnemer if (!Size) 546b58f32f7SDavid Majnemer return false; 547b58f32f7SDavid Majnemer 54824e6cc2dSKarthik Bhat int64_t CVSize = CV->getSExtValue(); 54924e6cc2dSKarthik Bhat if (CVSize % Size) 55024e6cc2dSKarthik Bhat return false; 551*1bbf15c5SJames Molloy auto *StepValue = ConstantInt::getSigned(CV->getType(), CVSize / Size); 552*1bbf15c5SJames Molloy 553*1bbf15c5SJames Molloy D = InductionDescriptor(StartValue, IK_PtrInduction, StepValue); 55424e6cc2dSKarthik Bhat return true; 55524e6cc2dSKarthik Bhat } 556c5b7b555SAshutosh Nema 557c5b7b555SAshutosh Nema /// \brief Returns the instructions that use values defined in the loop. 558c5b7b555SAshutosh Nema SmallVector<Instruction *, 8> llvm::findDefsUsedOutsideOfLoop(Loop *L) { 559c5b7b555SAshutosh Nema SmallVector<Instruction *, 8> UsedOutside; 560c5b7b555SAshutosh Nema 561c5b7b555SAshutosh Nema for (auto *Block : L->getBlocks()) 562c5b7b555SAshutosh Nema // FIXME: I believe that this could use copy_if if the Inst reference could 563c5b7b555SAshutosh Nema // be adapted into a pointer. 564c5b7b555SAshutosh Nema for (auto &Inst : *Block) { 565c5b7b555SAshutosh Nema auto Users = Inst.users(); 566c5b7b555SAshutosh Nema if (std::any_of(Users.begin(), Users.end(), [&](User *U) { 567c5b7b555SAshutosh Nema auto *Use = cast<Instruction>(U); 568c5b7b555SAshutosh Nema return !L->contains(Use->getParent()); 569c5b7b555SAshutosh Nema })) 570c5b7b555SAshutosh Nema UsedOutside.push_back(&Inst); 571c5b7b555SAshutosh Nema } 572c5b7b555SAshutosh Nema 573c5b7b555SAshutosh Nema return UsedOutside; 574c5b7b555SAshutosh Nema } 575