Back to home page

EIC code displayed by LXR

 
 

    


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