diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index 242ca836b32f..3b8c5490c669 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -169,8 +169,8 @@ namespace llvm { static bool classof(const SCEV *S); }; - /// SCEVPredicate - This class represents an assumption made using SCEV - /// expressions which can be checked at run-time. + /// This class represents an assumption made using SCEV expressions which can + /// be checked at run-time. class SCEVPredicate : public FoldingSetNode { friend struct FoldingSetTrait; @@ -237,10 +237,9 @@ namespace llvm { } }; - /// SCEVEqualPredicate - This class represents an assumption that two SCEV - /// expressions are equal, and this can be checked at run-time. We assume - /// that the left hand side is a SCEVUnknown and the right hand side a - /// constant. + /// This class represents an assumption that two SCEV expressions are equal, + /// and this can be checked at run-time. We assume that the left hand side is + /// a SCEVUnknown and the right hand side a constant. class SCEVEqualPredicate final : public SCEVPredicate { /// We assume that LHS == RHS, where LHS is a SCEVUnknown and RHS a /// constant. @@ -269,11 +268,10 @@ namespace llvm { } }; - /// SCEVWrapPredicate - This class represents an assumption made on an AddRec - /// expression. Given an affine AddRec expression {a,+,b}, we assume that it - /// has the nssw or nusw flags (defined below) in the first X iterations of - /// the loop, where X is a SCEV expression returned by - /// getPredicatedBackedgeTakenCount). + /// This class represents an assumption made on an AddRec expression. Given an + /// affine AddRec expression {a,+,b}, we assume that it has the nssw or nusw + /// flags (defined below) in the first X iterations of the loop, where X is a + /// SCEV expression returned by getPredicatedBackedgeTakenCount). /// /// Note that this does not imply that X is equal to the backedge taken /// count. This means that if we have a nusw predicate for i32 {0,+,1} with a @@ -368,9 +366,9 @@ namespace llvm { } }; - /// SCEVUnionPredicate - This class represents a composition of other - /// SCEV predicates, and is the class that most clients will interact with. - /// This is equivalent to a logical "AND" of all the predicates in the union. + /// This class represents a composition of other SCEV predicates, and is the + /// class that most clients will interact with. This is equivalent to a + /// logical "AND" of all the predicates in the union. class SCEVUnionPredicate final : public SCEVPredicate { private: typedef DenseMap> @@ -488,15 +486,14 @@ namespace llvm { /// This SCEV is used to represent unknown trip counts and things. std::unique_ptr CouldNotCompute; - /// HasRecMapType - The typedef for HasRecMap. + /// The typedef for HasRecMap. /// typedef DenseMap HasRecMapType; - /// HasRecMap -- This is a cache to record whether a SCEV contains - /// any scAddRecExpr. + /// This is a cache to record whether a SCEV contains any scAddRecExpr. HasRecMapType HasRecMap; - /// ExprValueMapType - The typedef for ExprValueMap. + /// The typedef for ExprValueMap. /// typedef DenseMap> ExprValueMapType; @@ -1105,9 +1102,9 @@ namespace llvm { bool isMonotonicPredicate(const SCEVAddRecExpr *LHS, ICmpInst::Predicate Pred, bool &Increasing); - // Return SCEV no-wrap flags that can be proven based on reasoning - // about how poison produced from no-wrap flags on this value - // (e.g. a nuw add) would trigger undefined behavior on overflow. + /// Return SCEV no-wrap flags that can be proven based on reasoning about + /// how poison produced from no-wrap flags on this value (e.g. a nuw add) + /// would trigger undefined behavior on overflow. SCEV::NoWrapFlags getNoWrapFlagsFromUB(const Value *V); /// Return true if the SCEV corresponding to \p I is never poison. Proving @@ -1157,16 +1154,15 @@ namespace llvm { /// return true. For pointer types, this is the pointer-sized integer type. Type *getEffectiveSCEVType(Type *Ty) const; - /// containsAddRecurrence - Return true if the SCEV is a scAddRecExpr or - /// it contains scAddRecExpr. The result will be cached in HasRecMap. + /// Return true if the SCEV is a scAddRecExpr or it contains + /// scAddRecExpr. The result will be cached in HasRecMap. /// bool containsAddRecurrence(const SCEV *S); - /// getSCEVValues - Return the Value set from which the SCEV expr is - /// generated. + /// Return the Value set from which the SCEV expr is generated. SetVector *getSCEVValues(const SCEV *S); - /// eraseValueFromMap - Erase Value from ValueExprMap and ExprValueMap. + /// Erase Value from ValueExprMap and ExprValueMap. void eraseValueFromMap(Value *V); /// Return a SCEV expression for the full generality of the specified @@ -1705,60 +1701,78 @@ namespace llvm { public: PredicatedScalarEvolution(ScalarEvolution &SE, Loop &L); const SCEVUnionPredicate &getUnionPredicate() const; + /// \brief Returns the SCEV expression of V, in the context of the current /// SCEV predicate. /// The order of transformations applied on the expression of V returned /// by ScalarEvolution is guaranteed to be preserved, even when adding new /// predicates. const SCEV *getSCEV(Value *V); + /// Get the (predicated) backedge count for the analyzed loop. const SCEV *getBackedgeTakenCount(); + /// \brief Adds a new predicate. void addPredicate(const SCEVPredicate &Pred); + /// \brief Attempts to produce an AddRecExpr for V by adding additional /// SCEV predicates. If we can't transform the expression into an /// AddRecExpr we return nullptr and not add additional SCEV predicates /// to the current context. const SCEVAddRecExpr *getAsAddRec(Value *V); + /// \brief Proves that V doesn't overflow by adding SCEV predicate. void setNoOverflow(Value *V, SCEVWrapPredicate::IncrementWrapFlags Flags); + /// \brief Returns true if we've proved that V doesn't wrap by means of a /// SCEV predicate. bool hasNoOverflow(Value *V, SCEVWrapPredicate::IncrementWrapFlags Flags); + /// \brief Returns the ScalarEvolution analysis used. ScalarEvolution *getSE() const { return &SE; } + /// We need to explicitly define the copy constructor because of FlagsMap. PredicatedScalarEvolution(const PredicatedScalarEvolution&); + /// Print the SCEV mappings done by the Predicated Scalar Evolution. /// The printed text is indented by \p Depth. void print(raw_ostream &OS, unsigned Depth) const; + private: /// \brief Increments the version number of the predicate. /// This needs to be called every time the SCEV predicate changes. void updateGeneration(); + /// Holds a SCEV and the version number of the SCEV predicate used to /// perform the rewrite of the expression. typedef std::pair RewriteEntry; + /// Maps a SCEV to the rewrite result of that SCEV at a certain version /// number. If this number doesn't match the current Generation, we will /// need to do a rewrite. To preserve the transformation order of previous /// rewrites, we will rewrite the previous result instead of the original /// SCEV. DenseMap RewriteMap; + /// Records what NoWrap flags we've added to a Value *. ValueMap FlagsMap; + /// The ScalarEvolution analysis. ScalarEvolution &SE; + /// The analyzed Loop. const Loop &L; + /// The SCEVPredicate that forms our context. We will rewrite all /// expressions assuming that this predicate true. SCEVUnionPredicate Preds; + /// Marks the version of the SCEV predicate used. When rewriting a SCEV /// expression we mark it with the version of the predicate. We use this to /// figure out if the predicate has changed from the last rewrite of the /// SCEV. If so, we need to perform a new rewrite. unsigned Generation; + /// The backedge taken count. const SCEV *BackedgeCount; }; diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h b/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h index 0fd26e3b6a74..dfb25f444242 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -32,9 +32,7 @@ namespace llvm { scUnknown, scCouldNotCompute }; - //===--------------------------------------------------------------------===// - /// SCEVConstant - This class represents a constant integer value. - /// + /// This class represents a constant integer value. class SCEVConstant : public SCEV { friend class ScalarEvolution; @@ -53,9 +51,7 @@ namespace llvm { } }; - //===--------------------------------------------------------------------===// - /// SCEVCastExpr - This is the base class for unary cast operator classes. - /// + /// This is the base class for unary cast operator classes. class SCEVCastExpr : public SCEV { protected: const SCEV *Op; @@ -76,10 +72,8 @@ namespace llvm { } }; - //===--------------------------------------------------------------------===// - /// SCEVTruncateExpr - This class represents a truncation of an integer value - /// to a smaller integer value. - /// + /// This class represents a truncation of an integer value to a + /// smaller integer value. class SCEVTruncateExpr : public SCEVCastExpr { friend class ScalarEvolution; @@ -93,10 +87,8 @@ namespace llvm { } }; - //===--------------------------------------------------------------------===// - /// SCEVZeroExtendExpr - This class represents a zero extension of a small - /// integer value to a larger integer value. - /// + /// This class represents a zero extension of a small integer value + /// to a larger integer value. class SCEVZeroExtendExpr : public SCEVCastExpr { friend class ScalarEvolution; @@ -110,10 +102,8 @@ namespace llvm { } }; - //===--------------------------------------------------------------------===// - /// SCEVSignExtendExpr - This class represents a sign extension of a small - /// integer value to a larger integer value. - /// + /// This class represents a sign extension of a small integer value + /// to a larger integer value. class SCEVSignExtendExpr : public SCEVCastExpr { friend class ScalarEvolution; @@ -128,10 +118,8 @@ namespace llvm { }; - //===--------------------------------------------------------------------===// - /// SCEVNAryExpr - This node is a base class providing common - /// functionality for n'ary operators. - /// + /// This node is a base class providing common functionality for + /// n'ary operators. class SCEVNAryExpr : public SCEV { protected: // Since SCEVs are immutable, ScalarEvolution allocates operand @@ -188,10 +176,7 @@ namespace llvm { } }; - //===--------------------------------------------------------------------===// - /// SCEVCommutativeExpr - This node is the base class for n'ary commutative - /// operators. - /// + /// This node is the base class for n'ary commutative operators. class SCEVCommutativeExpr : public SCEVNAryExpr { protected: SCEVCommutativeExpr(const FoldingSetNodeIDRef ID, @@ -214,9 +199,7 @@ namespace llvm { }; - //===--------------------------------------------------------------------===// - /// SCEVAddExpr - This node represents an addition of some number of SCEVs. - /// + /// This node represents an addition of some number of SCEVs. class SCEVAddExpr : public SCEVCommutativeExpr { friend class ScalarEvolution; @@ -239,9 +222,8 @@ namespace llvm { } }; - //===--------------------------------------------------------------------===// - /// SCEVMulExpr - This node represents multiplication of some number of SCEVs. - /// + + /// This node represents multiplication of some number of SCEVs. class SCEVMulExpr : public SCEVCommutativeExpr { friend class ScalarEvolution; @@ -258,9 +240,7 @@ namespace llvm { }; - //===--------------------------------------------------------------------===// - /// SCEVUDivExpr - This class represents a binary unsigned division operation. - /// + /// This class represents a binary unsigned division operation. class SCEVUDivExpr : public SCEV { friend class ScalarEvolution; @@ -289,12 +269,11 @@ namespace llvm { }; - //===--------------------------------------------------------------------===// - /// SCEVAddRecExpr - This node represents a polynomial recurrence on the trip - /// count of the specified loop. This is the primary focus of the - /// ScalarEvolution framework; all the other SCEV subclasses are mostly just - /// supporting infrastructure to allow SCEVAddRecExpr expressions to be - /// created and analyzed. + /// This node represents a polynomial recurrence on the trip count + /// of the specified loop. This is the primary focus of the + /// ScalarEvolution framework; all the other SCEV subclasses are + /// mostly just supporting infrastructure to allow SCEVAddRecExpr + /// expressions to be created and analyzed. /// /// All operands of an AddRec are required to be loop invariant. /// @@ -311,10 +290,10 @@ namespace llvm { const SCEV *getStart() const { return Operands[0]; } const Loop *getLoop() const { return L; } - /// getStepRecurrence - This method constructs and returns the recurrence - /// indicating how much this expression steps by. If this is a polynomial - /// of degree N, it returns a chrec of degree N-1. - /// We cannot determine whether the step recurrence has self-wraparound. + /// Constructs and returns the recurrence indicating how much this + /// expression steps by. If this is a polynomial of degree N, it + /// returns a chrec of degree N-1. We cannot determine whether + /// the step recurrence has self-wraparound. const SCEV *getStepRecurrence(ScalarEvolution &SE) const { if (isAffine()) return getOperand(1); return SE.getAddRecExpr(SmallVector(op_begin()+1, @@ -322,17 +301,17 @@ namespace llvm { getLoop(), FlagAnyWrap); } - /// isAffine - Return true if this represents an expression - /// A + B*x where A and B are loop invariant values. + /// Return true if this represents an expression A + B*x where A + /// and B are loop invariant values. bool isAffine() const { // We know that the start value is invariant. This expression is thus // affine iff the step is also invariant. return getNumOperands() == 2; } - /// isQuadratic - Return true if this represents an expression - /// A + B*x + C*x^2 where A, B and C are loop invariant values. - /// This corresponds to an addrec of the form {L,+,M,+,N} + /// Return true if this represents an expression A + B*x + C*x^2 + /// where A, B and C are loop invariant values. This corresponds + /// to an addrec of the form {L,+,M,+,N} bool isQuadratic() const { return getNumOperands() == 3; } @@ -346,21 +325,21 @@ namespace llvm { SubclassData |= Flags; } - /// evaluateAtIteration - Return the value of this chain of recurrences at - /// the specified iteration number. + /// Return the value of this chain of recurrences at the specified + /// iteration number. const SCEV *evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const; - /// getNumIterationsInRange - Return the number of iterations of this loop - /// that produce values in the specified constant range. Another way of - /// looking at this is that it returns the first iteration number where the - /// value is not in the condition, thus computing the exit count. If the - /// iteration count can't be computed, an instance of SCEVCouldNotCompute is - /// returned. + /// Return the number of iterations of this loop that produce + /// values in the specified constant range. Another way of + /// looking at this is that it returns the first iteration number + /// where the value is not in the condition, thus computing the + /// exit count. If the iteration count can't be computed, an + /// instance of SCEVCouldNotCompute is returned. const SCEV *getNumIterationsInRange(ConstantRange Range, ScalarEvolution &SE) const; - /// getPostIncExpr - Return an expression representing the value of - /// this expression one iteration of the loop ahead. + /// Return an expression representing the value of this expression + /// one iteration of the loop ahead. const SCEVAddRecExpr *getPostIncExpr(ScalarEvolution &SE) const { return cast(SE.getAddExpr(this, getStepRecurrence(SE))); } @@ -371,9 +350,7 @@ namespace llvm { } }; - //===--------------------------------------------------------------------===// - /// SCEVSMaxExpr - This class represents a signed maximum selection. - /// + /// This class represents a signed maximum selection. class SCEVSMaxExpr : public SCEVCommutativeExpr { friend class ScalarEvolution; @@ -392,9 +369,7 @@ namespace llvm { }; - //===--------------------------------------------------------------------===// - /// SCEVUMaxExpr - This class represents an unsigned maximum selection. - /// + /// This class represents an unsigned maximum selection. class SCEVUMaxExpr : public SCEVCommutativeExpr { friend class ScalarEvolution; @@ -412,11 +387,9 @@ namespace llvm { } }; - //===--------------------------------------------------------------------===// - /// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV - /// value, and only represent it as its LLVM Value. This is the "bottom" - /// value for the analysis. - /// + /// This means that we are dealing with an entirely unknown SCEV + /// value, and only represent it as its LLVM Value. This is the + /// "bottom" value for the analysis. class SCEVUnknown final : public SCEV, private CallbackVH { friend class ScalarEvolution; @@ -424,13 +397,13 @@ namespace llvm { void deleted() override; void allUsesReplacedWith(Value *New) override; - /// SE - The parent ScalarEvolution value. This is used to update - /// the parent's maps when the value associated with a SCEVUnknown - /// is deleted or RAUW'd. + /// The parent ScalarEvolution value. This is used to update the + /// parent's maps when the value associated with a SCEVUnknown is + /// deleted or RAUW'd. ScalarEvolution *SE; - /// Next - The next pointer in the linked list of all - /// SCEVUnknown instances owned by a ScalarEvolution. + /// The next pointer in the linked list of all SCEVUnknown + /// instances owned by a ScalarEvolution. SCEVUnknown *Next; SCEVUnknown(const FoldingSetNodeIDRef ID, Value *V, @@ -440,15 +413,17 @@ namespace llvm { public: Value *getValue() const { return getValPtr(); } - /// isSizeOf, isAlignOf, isOffsetOf - Test whether this is a special - /// constant representing a type size, alignment, or field offset in - /// a target-independent manner, and hasn't happened to have been - /// folded with other operations into something unrecognizable. This - /// is mainly only useful for pretty-printing and other situations - /// where it isn't absolutely required for these to succeed. + /// @{ + /// Test whether this is a special constant representing a type + /// size, alignment, or field offset in a target-independent + /// manner, and hasn't happened to have been folded with other + /// operations into something unrecognizable. This is mainly only + /// useful for pretty-printing and other situations where it isn't + /// absolutely required for these to succeed. bool isSizeOf(Type *&AllocTy) const; bool isAlignOf(Type *&AllocTy) const; bool isOffsetOf(Type *&STy, Constant *&FieldNo) const; + /// @} Type *getType() const { return getValPtr()->getType(); } @@ -458,8 +433,8 @@ namespace llvm { } }; - /// SCEVVisitor - This class defines a simple visitor class that may be used - /// for various SCEV analysis purposes. + /// This class defines a simple visitor class that may be used for + /// various SCEV analysis purposes. template struct SCEVVisitor { RetVal visit(const SCEV *S) {