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<SCEVPredicate>;
}
};
- /// 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.
}
};
- /// 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
}
};
- /// 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<const SCEV *, SmallVector<const SCEVPredicate *, 4>>
/// This SCEV is used to represent unknown trip counts and things.
std::unique_ptr<SCEVCouldNotCompute> CouldNotCompute;
- /// HasRecMapType - The typedef for HasRecMap.
+ /// The typedef for HasRecMap.
///
typedef DenseMap<const SCEV *, bool> 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<const SCEV *, SetVector<Value *>> ExprValueMapType;
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
/// 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<Value *> *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
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<unsigned, const SCEV *> 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<const SCEV *, RewriteEntry> RewriteMap;
+
/// Records what NoWrap flags we've added to a Value *.
ValueMap<Value *, SCEVWrapPredicate::IncrementWrapFlags> 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;
};
scUnknown, scCouldNotCompute
};
- //===--------------------------------------------------------------------===//
- /// SCEVConstant - This class represents a constant integer value.
- ///
+ /// This class represents a constant integer value.
class SCEVConstant : public SCEV {
friend class ScalarEvolution;
}
};
- //===--------------------------------------------------------------------===//
- /// 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;
}
};
- //===--------------------------------------------------------------------===//
- /// 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;
}
};
- //===--------------------------------------------------------------------===//
- /// 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;
}
};
- //===--------------------------------------------------------------------===//
- /// 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;
};
- //===--------------------------------------------------------------------===//
- /// 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
}
};
- //===--------------------------------------------------------------------===//
- /// 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,
};
- //===--------------------------------------------------------------------===//
- /// 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;
}
};
- //===--------------------------------------------------------------------===//
- /// 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;
};
- //===--------------------------------------------------------------------===//
- /// SCEVUDivExpr - This class represents a binary unsigned division operation.
- ///
+ /// This class represents a binary unsigned division operation.
class SCEVUDivExpr : public SCEV {
friend class ScalarEvolution;
};
- //===--------------------------------------------------------------------===//
- /// 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.
///
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<const SCEV *, 3>(op_begin()+1,
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;
}
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<SCEVAddRecExpr>(SE.getAddExpr(this, getStepRecurrence(SE)));
}
}
};
- //===--------------------------------------------------------------------===//
- /// SCEVSMaxExpr - This class represents a signed maximum selection.
- ///
+ /// This class represents a signed maximum selection.
class SCEVSMaxExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
};
- //===--------------------------------------------------------------------===//
- /// SCEVUMaxExpr - This class represents an unsigned maximum selection.
- ///
+ /// This class represents an unsigned maximum selection.
class SCEVUMaxExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
}
};
- //===--------------------------------------------------------------------===//
- /// 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;
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,
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(); }
}
};
- /// 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<typename SC, typename RetVal=void>
struct SCEVVisitor {
RetVal visit(const SCEV *S) {