|
|
|||
File indexing completed on 2026-05-10 08:43:13
0001 //===- llvm/Analysis/IVDescriptors.h - IndVar Descriptors -------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // This file "describes" induction and recurrence variables. 0010 // 0011 //===----------------------------------------------------------------------===// 0012 0013 #ifndef LLVM_ANALYSIS_IVDESCRIPTORS_H 0014 #define LLVM_ANALYSIS_IVDESCRIPTORS_H 0015 0016 #include "llvm/ADT/SmallPtrSet.h" 0017 #include "llvm/ADT/SmallVector.h" 0018 #include "llvm/IR/IntrinsicInst.h" 0019 #include "llvm/IR/ValueHandle.h" 0020 0021 namespace llvm { 0022 0023 class AssumptionCache; 0024 class DemandedBits; 0025 class DominatorTree; 0026 class Loop; 0027 class PredicatedScalarEvolution; 0028 class ScalarEvolution; 0029 class SCEV; 0030 class StoreInst; 0031 0032 /// These are the kinds of recurrences that we support. 0033 enum class RecurKind { 0034 None, ///< Not a recurrence. 0035 Add, ///< Sum of integers. 0036 Mul, ///< Product of integers. 0037 Or, ///< Bitwise or logical OR of integers. 0038 And, ///< Bitwise or logical AND of integers. 0039 Xor, ///< Bitwise or logical XOR of integers. 0040 SMin, ///< Signed integer min implemented in terms of select(cmp()). 0041 SMax, ///< Signed integer max implemented in terms of select(cmp()). 0042 UMin, ///< Unsigned integer min implemented in terms of select(cmp()). 0043 UMax, ///< Unsigned integer max implemented in terms of select(cmp()). 0044 FAdd, ///< Sum of floats. 0045 FMul, ///< Product of floats. 0046 FMin, ///< FP min implemented in terms of select(cmp()). 0047 FMax, ///< FP max implemented in terms of select(cmp()). 0048 FMinimum, ///< FP min with llvm.minimum semantics 0049 FMaximum, ///< FP max with llvm.maximum semantics 0050 FMulAdd, ///< Sum of float products with llvm.fmuladd(a * b + sum). 0051 IAnyOf, ///< Any_of reduction with select(icmp(),x,y) where one of (x,y) is 0052 ///< loop invariant, and both x and y are integer type. 0053 FAnyOf, ///< Any_of reduction with select(fcmp(),x,y) where one of (x,y) is 0054 ///< loop invariant, and both x and y are integer type. 0055 IFindLastIV, ///< FindLast reduction with select(icmp(),x,y) where one of 0056 ///< (x,y) is increasing loop induction, and both x and y are 0057 ///< integer type. 0058 FFindLastIV ///< FindLast reduction with select(fcmp(),x,y) where one of (x,y) 0059 ///< is increasing loop induction, and both x and y are integer 0060 ///< type. 0061 // TODO: Any_of and FindLast reduction need not be restricted to integer type 0062 // only. 0063 }; 0064 0065 /// The RecurrenceDescriptor is used to identify recurrences variables in a 0066 /// loop. Reduction is a special case of recurrence that has uses of the 0067 /// recurrence variable outside the loop. The method isReductionPHI identifies 0068 /// reductions that are basic recurrences. 0069 /// 0070 /// Basic recurrences are defined as the summation, product, OR, AND, XOR, min, 0071 /// or max of a set of terms. For example: for(i=0; i<n; i++) { total += 0072 /// array[i]; } is a summation of array elements. Basic recurrences are a 0073 /// special case of chains of recurrences (CR). See ScalarEvolution for CR 0074 /// references. 0075 0076 /// This struct holds information about recurrence variables. 0077 class RecurrenceDescriptor { 0078 public: 0079 RecurrenceDescriptor() = default; 0080 0081 RecurrenceDescriptor(Value *Start, Instruction *Exit, StoreInst *Store, 0082 RecurKind K, FastMathFlags FMF, Instruction *ExactFP, 0083 Type *RT, bool Signed, bool Ordered, 0084 SmallPtrSetImpl<Instruction *> &CI, 0085 unsigned MinWidthCastToRecurTy) 0086 : IntermediateStore(Store), StartValue(Start), LoopExitInstr(Exit), 0087 Kind(K), FMF(FMF), ExactFPMathInst(ExactFP), RecurrenceType(RT), 0088 IsSigned(Signed), IsOrdered(Ordered), 0089 MinWidthCastToRecurrenceType(MinWidthCastToRecurTy) { 0090 CastInsts.insert(CI.begin(), CI.end()); 0091 } 0092 0093 /// This POD struct holds information about a potential recurrence operation. 0094 class InstDesc { 0095 public: 0096 InstDesc(bool IsRecur, Instruction *I, Instruction *ExactFP = nullptr) 0097 : IsRecurrence(IsRecur), PatternLastInst(I), 0098 RecKind(RecurKind::None), ExactFPMathInst(ExactFP) {} 0099 0100 InstDesc(Instruction *I, RecurKind K, Instruction *ExactFP = nullptr) 0101 : IsRecurrence(true), PatternLastInst(I), RecKind(K), 0102 ExactFPMathInst(ExactFP) {} 0103 0104 bool isRecurrence() const { return IsRecurrence; } 0105 0106 bool needsExactFPMath() const { return ExactFPMathInst != nullptr; } 0107 0108 Instruction *getExactFPMathInst() const { return ExactFPMathInst; } 0109 0110 RecurKind getRecKind() const { return RecKind; } 0111 0112 Instruction *getPatternInst() const { return PatternLastInst; } 0113 0114 private: 0115 // Is this instruction a recurrence candidate. 0116 bool IsRecurrence; 0117 // The last instruction in a min/max pattern (select of the select(icmp()) 0118 // pattern), or the current recurrence instruction otherwise. 0119 Instruction *PatternLastInst; 0120 // If this is a min/max pattern. 0121 RecurKind RecKind; 0122 // Recurrence does not allow floating-point reassociation. 0123 Instruction *ExactFPMathInst; 0124 }; 0125 0126 /// Returns a struct describing if the instruction 'I' can be a recurrence 0127 /// variable of type 'Kind' for a Loop \p L and reduction PHI \p Phi. 0128 /// If the recurrence is a min/max pattern of select(icmp()) this function 0129 /// advances the instruction pointer 'I' from the compare instruction to the 0130 /// select instruction and stores this pointer in 'PatternLastInst' member of 0131 /// the returned struct. 0132 static InstDesc isRecurrenceInstr(Loop *L, PHINode *Phi, Instruction *I, 0133 RecurKind Kind, InstDesc &Prev, 0134 FastMathFlags FuncFMF, ScalarEvolution *SE); 0135 0136 /// Returns true if instruction I has multiple uses in Insts 0137 static bool hasMultipleUsesOf(Instruction *I, 0138 SmallPtrSetImpl<Instruction *> &Insts, 0139 unsigned MaxNumUses); 0140 0141 /// Returns true if all uses of the instruction I is within the Set. 0142 static bool areAllUsesIn(Instruction *I, SmallPtrSetImpl<Instruction *> &Set); 0143 0144 /// Returns a struct describing if the instruction is a llvm.(s/u)(min/max), 0145 /// llvm.minnum/maxnum or a Select(ICmp(X, Y), X, Y) pair of instructions 0146 /// corresponding to a min(X, Y) or max(X, Y), matching the recurrence kind \p 0147 /// Kind. \p Prev specifies the description of an already processed select 0148 /// instruction, so its corresponding cmp can be matched to it. 0149 static InstDesc isMinMaxPattern(Instruction *I, RecurKind Kind, 0150 const InstDesc &Prev); 0151 0152 /// Returns a struct describing whether the instruction is either a 0153 /// Select(ICmp(A, B), X, Y), or 0154 /// Select(FCmp(A, B), X, Y) 0155 /// where one of (X, Y) is a loop invariant integer and the other is a PHI 0156 /// value. \p Prev specifies the description of an already processed select 0157 /// instruction, so its corresponding cmp can be matched to it. 0158 static InstDesc isAnyOfPattern(Loop *Loop, PHINode *OrigPhi, Instruction *I, 0159 InstDesc &Prev); 0160 0161 /// Returns a struct describing whether the instruction is either a 0162 /// Select(ICmp(A, B), X, Y), or 0163 /// Select(FCmp(A, B), X, Y) 0164 /// where one of (X, Y) is an increasing loop induction variable, and the 0165 /// other is a PHI value. 0166 // TODO: Support non-monotonic variable. FindLast does not need be restricted 0167 // to increasing loop induction variables. 0168 static InstDesc isFindLastIVPattern(Loop *TheLoop, PHINode *OrigPhi, 0169 Instruction *I, ScalarEvolution &SE); 0170 0171 /// Returns a struct describing if the instruction is a 0172 /// Select(FCmp(X, Y), (Z = X op PHINode), PHINode) instruction pattern. 0173 static InstDesc isConditionalRdxPattern(RecurKind Kind, Instruction *I); 0174 0175 /// Returns the opcode corresponding to the RecurrenceKind. 0176 static unsigned getOpcode(RecurKind Kind); 0177 0178 /// Returns true if Phi is a reduction of type Kind and adds it to the 0179 /// RecurrenceDescriptor. If either \p DB is non-null or \p AC and \p DT are 0180 /// non-null, the minimal bit width needed to compute the reduction will be 0181 /// computed. 0182 static bool 0183 AddReductionVar(PHINode *Phi, RecurKind Kind, Loop *TheLoop, 0184 FastMathFlags FuncFMF, RecurrenceDescriptor &RedDes, 0185 DemandedBits *DB = nullptr, AssumptionCache *AC = nullptr, 0186 DominatorTree *DT = nullptr, ScalarEvolution *SE = nullptr); 0187 0188 /// Returns true if Phi is a reduction in TheLoop. The RecurrenceDescriptor 0189 /// is returned in RedDes. If either \p DB is non-null or \p AC and \p DT are 0190 /// non-null, the minimal bit width needed to compute the reduction will be 0191 /// computed. If \p SE is non-null, store instructions to loop invariant 0192 /// addresses are processed. 0193 static bool 0194 isReductionPHI(PHINode *Phi, Loop *TheLoop, RecurrenceDescriptor &RedDes, 0195 DemandedBits *DB = nullptr, AssumptionCache *AC = nullptr, 0196 DominatorTree *DT = nullptr, ScalarEvolution *SE = nullptr); 0197 0198 /// Returns true if Phi is a fixed-order recurrence. A fixed-order recurrence 0199 /// is a non-reduction recurrence relation in which the value of the 0200 /// recurrence in the current loop iteration equals a value defined in a 0201 /// previous iteration (e.g. if the value is defined in the previous 0202 /// iteration, we refer to it as first-order recurrence, if it is defined in 0203 /// the iteration before the previous, we refer to it as second-order 0204 /// recurrence and so on). Note that this function optimistically assumes that 0205 /// uses of the recurrence can be re-ordered if necessary and users need to 0206 /// check and perform the re-ordering. 0207 static bool isFixedOrderRecurrence(PHINode *Phi, Loop *TheLoop, 0208 DominatorTree *DT); 0209 0210 RecurKind getRecurrenceKind() const { return Kind; } 0211 0212 unsigned getOpcode() const { return getOpcode(getRecurrenceKind()); } 0213 0214 FastMathFlags getFastMathFlags() const { return FMF; } 0215 0216 TrackingVH<Value> getRecurrenceStartValue() const { return StartValue; } 0217 0218 Instruction *getLoopExitInstr() const { return LoopExitInstr; } 0219 0220 /// Returns true if the recurrence has floating-point math that requires 0221 /// precise (ordered) operations. 0222 bool hasExactFPMath() const { return ExactFPMathInst != nullptr; } 0223 0224 /// Returns 1st non-reassociative FP instruction in the PHI node's use-chain. 0225 Instruction *getExactFPMathInst() const { return ExactFPMathInst; } 0226 0227 /// Returns true if the recurrence kind is an integer kind. 0228 static bool isIntegerRecurrenceKind(RecurKind Kind); 0229 0230 /// Returns true if the recurrence kind is a floating point kind. 0231 static bool isFloatingPointRecurrenceKind(RecurKind Kind); 0232 0233 /// Returns true if the recurrence kind is an integer min/max kind. 0234 static bool isIntMinMaxRecurrenceKind(RecurKind Kind) { 0235 return Kind == RecurKind::UMin || Kind == RecurKind::UMax || 0236 Kind == RecurKind::SMin || Kind == RecurKind::SMax; 0237 } 0238 0239 /// Returns true if the recurrence kind is a floating-point min/max kind. 0240 static bool isFPMinMaxRecurrenceKind(RecurKind Kind) { 0241 return Kind == RecurKind::FMin || Kind == RecurKind::FMax || 0242 Kind == RecurKind::FMinimum || Kind == RecurKind::FMaximum; 0243 } 0244 0245 /// Returns true if the recurrence kind is any min/max kind. 0246 static bool isMinMaxRecurrenceKind(RecurKind Kind) { 0247 return isIntMinMaxRecurrenceKind(Kind) || isFPMinMaxRecurrenceKind(Kind); 0248 } 0249 0250 /// Returns true if the recurrence kind is of the form 0251 /// select(cmp(),x,y) where one of (x,y) is loop invariant. 0252 static bool isAnyOfRecurrenceKind(RecurKind Kind) { 0253 return Kind == RecurKind::IAnyOf || Kind == RecurKind::FAnyOf; 0254 } 0255 0256 /// Returns true if the recurrence kind is of the form 0257 /// select(cmp(),x,y) where one of (x,y) is increasing loop induction. 0258 static bool isFindLastIVRecurrenceKind(RecurKind Kind) { 0259 return Kind == RecurKind::IFindLastIV || Kind == RecurKind::FFindLastIV; 0260 } 0261 0262 /// Returns the type of the recurrence. This type can be narrower than the 0263 /// actual type of the Phi if the recurrence has been type-promoted. 0264 Type *getRecurrenceType() const { return RecurrenceType; } 0265 0266 /// Returns the sentinel value for FindLastIV recurrences to replace the start 0267 /// value. 0268 Value *getSentinelValue() const { 0269 assert(isFindLastIVRecurrenceKind(Kind) && "Unexpected recurrence kind"); 0270 Type *Ty = StartValue->getType(); 0271 return ConstantInt::get(Ty, 0272 APInt::getSignedMinValue(Ty->getIntegerBitWidth())); 0273 } 0274 0275 /// Returns a reference to the instructions used for type-promoting the 0276 /// recurrence. 0277 const SmallPtrSet<Instruction *, 8> &getCastInsts() const { return CastInsts; } 0278 0279 /// Returns the minimum width used by the recurrence in bits. 0280 unsigned getMinWidthCastToRecurrenceTypeInBits() const { 0281 return MinWidthCastToRecurrenceType; 0282 } 0283 0284 /// Returns true if all source operands of the recurrence are SExtInsts. 0285 bool isSigned() const { return IsSigned; } 0286 0287 /// Expose an ordered FP reduction to the instance users. 0288 bool isOrdered() const { return IsOrdered; } 0289 0290 /// Attempts to find a chain of operations from Phi to LoopExitInst that can 0291 /// be treated as a set of reductions instructions for in-loop reductions. 0292 SmallVector<Instruction *, 4> getReductionOpChain(PHINode *Phi, 0293 Loop *L) const; 0294 0295 /// Returns true if the instruction is a call to the llvm.fmuladd intrinsic. 0296 static bool isFMulAddIntrinsic(Instruction *I) { 0297 return isa<IntrinsicInst>(I) && 0298 cast<IntrinsicInst>(I)->getIntrinsicID() == Intrinsic::fmuladd; 0299 } 0300 0301 /// Reductions may store temporary or final result to an invariant address. 0302 /// If there is such a store in the loop then, after successfull run of 0303 /// AddReductionVar method, this field will be assigned the last met store. 0304 StoreInst *IntermediateStore = nullptr; 0305 0306 private: 0307 // The starting value of the recurrence. 0308 // It does not have to be zero! 0309 TrackingVH<Value> StartValue; 0310 // The instruction who's value is used outside the loop. 0311 Instruction *LoopExitInstr = nullptr; 0312 // The kind of the recurrence. 0313 RecurKind Kind = RecurKind::None; 0314 // The fast-math flags on the recurrent instructions. We propagate these 0315 // fast-math flags into the vectorized FP instructions we generate. 0316 FastMathFlags FMF; 0317 // First instance of non-reassociative floating-point in the PHI's use-chain. 0318 Instruction *ExactFPMathInst = nullptr; 0319 // The type of the recurrence. 0320 Type *RecurrenceType = nullptr; 0321 // True if all source operands of the recurrence are SExtInsts. 0322 bool IsSigned = false; 0323 // True if this recurrence can be treated as an in-order reduction. 0324 // Currently only a non-reassociative FAdd can be considered in-order, 0325 // if it is also the only FAdd in the PHI's use chain. 0326 bool IsOrdered = false; 0327 // Instructions used for type-promoting the recurrence. 0328 SmallPtrSet<Instruction *, 8> CastInsts; 0329 // The minimum width used by the recurrence. 0330 unsigned MinWidthCastToRecurrenceType; 0331 }; 0332 0333 /// A struct for saving information about induction variables. 0334 class InductionDescriptor { 0335 public: 0336 /// This enum represents the kinds of inductions that we support. 0337 enum InductionKind { 0338 IK_NoInduction, ///< Not an induction variable. 0339 IK_IntInduction, ///< Integer induction variable. Step = C. 0340 IK_PtrInduction, ///< Pointer induction var. Step = C. 0341 IK_FpInduction ///< Floating point induction variable. 0342 }; 0343 0344 public: 0345 /// Default constructor - creates an invalid induction. 0346 InductionDescriptor() = default; 0347 0348 Value *getStartValue() const { return StartValue; } 0349 InductionKind getKind() const { return IK; } 0350 const SCEV *getStep() const { return Step; } 0351 BinaryOperator *getInductionBinOp() const { return InductionBinOp; } 0352 ConstantInt *getConstIntStepValue() const; 0353 0354 /// Returns true if \p Phi is an induction in the loop \p L. If \p Phi is an 0355 /// induction, the induction descriptor \p D will contain the data describing 0356 /// this induction. Since Induction Phis can only be present inside loop 0357 /// headers, the function will assert if it is passed a Phi whose parent is 0358 /// not the loop header. If by some other means the caller has a better SCEV 0359 /// expression for \p Phi than the one returned by the ScalarEvolution 0360 /// analysis, it can be passed through \p Expr. If the def-use chain 0361 /// associated with the phi includes casts (that we know we can ignore 0362 /// under proper runtime checks), they are passed through \p CastsToIgnore. 0363 static bool 0364 isInductionPHI(PHINode *Phi, const Loop *L, ScalarEvolution *SE, 0365 InductionDescriptor &D, const SCEV *Expr = nullptr, 0366 SmallVectorImpl<Instruction *> *CastsToIgnore = nullptr); 0367 0368 /// Returns true if \p Phi is a floating point induction in the loop \p L. 0369 /// If \p Phi is an induction, the induction descriptor \p D will contain 0370 /// the data describing this induction. 0371 static bool isFPInductionPHI(PHINode *Phi, const Loop *L, ScalarEvolution *SE, 0372 InductionDescriptor &D); 0373 0374 /// Returns true if \p Phi is a loop \p L induction, in the context associated 0375 /// with the run-time predicate of PSE. If \p Assume is true, this can add 0376 /// further SCEV predicates to \p PSE in order to prove that \p Phi is an 0377 /// induction. 0378 /// If \p Phi is an induction, \p D will contain the data describing this 0379 /// induction. 0380 static bool isInductionPHI(PHINode *Phi, const Loop *L, 0381 PredicatedScalarEvolution &PSE, 0382 InductionDescriptor &D, bool Assume = false); 0383 0384 /// Returns floating-point induction operator that does not allow 0385 /// reassociation (transforming the induction requires an override of normal 0386 /// floating-point rules). 0387 Instruction *getExactFPMathInst() { 0388 if (IK == IK_FpInduction && InductionBinOp && 0389 !InductionBinOp->hasAllowReassoc()) 0390 return InductionBinOp; 0391 return nullptr; 0392 } 0393 0394 /// Returns binary opcode of the induction operator. 0395 Instruction::BinaryOps getInductionOpcode() const { 0396 return InductionBinOp ? InductionBinOp->getOpcode() 0397 : Instruction::BinaryOpsEnd; 0398 } 0399 0400 /// Returns a reference to the type cast instructions in the induction 0401 /// update chain, that are redundant when guarded with a runtime 0402 /// SCEV overflow check. 0403 const SmallVectorImpl<Instruction *> &getCastInsts() const { 0404 return RedundantCasts; 0405 } 0406 0407 private: 0408 /// Private constructor - used by \c isInductionPHI. 0409 InductionDescriptor(Value *Start, InductionKind K, const SCEV *Step, 0410 BinaryOperator *InductionBinOp = nullptr, 0411 SmallVectorImpl<Instruction *> *Casts = nullptr); 0412 0413 /// Start value. 0414 TrackingVH<Value> StartValue; 0415 /// Induction kind. 0416 InductionKind IK = IK_NoInduction; 0417 /// Step value. 0418 const SCEV *Step = nullptr; 0419 // Instruction that advances induction variable. 0420 BinaryOperator *InductionBinOp = nullptr; 0421 // Instructions used for type-casts of the induction variable, 0422 // that are redundant when guarded with a runtime SCEV overflow check. 0423 SmallVector<Instruction *, 2> RedundantCasts; 0424 }; 0425 0426 } // end namespace llvm 0427 0428 #endif // LLVM_ANALYSIS_IVDESCRIPTORS_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|