diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 8a2a8dceefb..0d880ed74a8 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -63,7 +63,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" @@ -101,13 +101,6 @@ namespace { // Implementation of the SCEV class. // namespace { - enum SCEVTypes { - // These should be ordered in terms of increasing complexity to make the - // folders simpler. - scConstant, scTruncate, scZeroExtend, scAddExpr, scMulExpr, scUDivExpr, - scAddRecExpr, scUnknown, scCouldNotCompute - }; - /// SCEVComplexityCompare - Return true if the complexity of the LHS is less /// than the complexity of the RHS. If the SCEVs have identical complexity, /// order them by their addresses. This comparator is used to canonicalize @@ -172,593 +165,181 @@ bool SCEVCouldNotCompute::classof(const SCEV *S) { } -//===----------------------------------------------------------------------===// -// SCEVConstant - This class represents a constant integer value. -// -namespace { - class SCEVConstant; - // SCEVConstants - Only allow the creation of one SCEVConstant for any - // particular value. Don't use a SCEVHandle here, or else the object will - // never be deleted! - std::map SCEVConstants; +// SCEVConstants - Only allow the creation of one SCEVConstant for any +// particular value. Don't use a SCEVHandle here, or else the object will +// never be deleted! +static std::map SCEVConstants; + - class SCEVConstant : public SCEV { - ConstantInt *V; - SCEVConstant(ConstantInt *v) : SCEV(scConstant), V(v) {} +SCEVConstant::~SCEVConstant() { + SCEVConstants.erase(V); +} - virtual ~SCEVConstant() { - SCEVConstants.erase(V); - } - public: - /// get method - This just gets and returns a new SCEVConstant object. - /// - static SCEVHandle get(ConstantInt *V) { - // Make sure that SCEVConstant instances are all unsigned. - if (V->getType()->isSigned()) { - const Type *NewTy = V->getType()->getUnsignedVersion(); - V = cast(ConstantExpr::getCast(V, NewTy)); - } +SCEVHandle SCEVConstant::get(ConstantInt *V) { + // Make sure that SCEVConstant instances are all unsigned. + if (V->getType()->isSigned()) { + const Type *NewTy = V->getType()->getUnsignedVersion(); + V = cast(ConstantExpr::getCast(V, NewTy)); + } + + SCEVConstant *&R = SCEVConstants[V]; + if (R == 0) R = new SCEVConstant(V); + return R; +} - SCEVConstant *&R = SCEVConstants[V]; - if (R == 0) R = new SCEVConstant(V); - return R; - } +ConstantRange SCEVConstant::getValueRange() const { + return ConstantRange(V); +} - ConstantInt *getValue() const { return V; } +const Type *SCEVConstant::getType() const { return V->getType(); } - /// getValueRange - Return the tightest constant bounds that this value is - /// known to have. This method is only valid on integer SCEV objects. - virtual ConstantRange getValueRange() const { - return ConstantRange(V); - } +void SCEVConstant::print(std::ostream &OS) const { + WriteAsOperand(OS, V, false); +} - virtual bool isLoopInvariant(const Loop *L) const { - return true; - } +// SCEVTruncates - Only allow the creation of one SCEVTruncateExpr for any +// particular input. Don't use a SCEVHandle here, or else the object will +// never be deleted! +static std::map, SCEVTruncateExpr*> SCEVTruncates; - virtual bool hasComputableLoopEvolution(const Loop *L) const { - return false; // Not loop variant - } +SCEVTruncateExpr::SCEVTruncateExpr(const SCEVHandle &op, const Type *ty) + : SCEV(scTruncate), Op(op), Ty(ty) { + assert(Op->getType()->isInteger() && Ty->isInteger() && + Ty->isUnsigned() && + "Cannot truncate non-integer value!"); + assert(Op->getType()->getPrimitiveSize() > Ty->getPrimitiveSize() && + "This is not a truncating conversion!"); +} - virtual const Type *getType() const { return V->getType(); } +SCEVTruncateExpr::~SCEVTruncateExpr() { + SCEVTruncates.erase(std::make_pair(Op, Ty)); +} - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt) { - return getValue(); - } - - virtual void print(std::ostream &OS) const { - WriteAsOperand(OS, V, false); - } +ConstantRange SCEVTruncateExpr::getValueRange() const { + return getOperand()->getValueRange().truncate(getType()); +} - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVConstant *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scConstant; - } - }; +void SCEVTruncateExpr::print(std::ostream &OS) const { + OS << "(truncate " << *Op << " to " << *Ty << ")"; +} + +// SCEVZeroExtends - Only allow the creation of one SCEVZeroExtendExpr for any +// particular input. Don't use a SCEVHandle here, or else the object will never +// be deleted! +static std::map, + SCEVZeroExtendExpr*> SCEVZeroExtends; + +SCEVZeroExtendExpr::SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty) + : SCEV(scTruncate), Op(Op), Ty(ty) { + assert(Op->getType()->isInteger() && Ty->isInteger() && + Ty->isUnsigned() && + "Cannot zero extend non-integer value!"); + assert(Op->getType()->getPrimitiveSize() < Ty->getPrimitiveSize() && + "This is not an extending conversion!"); +} + +SCEVZeroExtendExpr::~SCEVZeroExtendExpr() { + SCEVZeroExtends.erase(std::make_pair(Op, Ty)); +} + +ConstantRange SCEVZeroExtendExpr::getValueRange() const { + return getOperand()->getValueRange().zeroExtend(getType()); +} + +void SCEVZeroExtendExpr::print(std::ostream &OS) const { + OS << "(zeroextend " << *Op << " to " << *Ty << ")"; +} + +// SCEVCommExprs - Only allow the creation of one SCEVCommutativeExpr for any +// particular input. Don't use a SCEVHandle here, or else the object will never +// be deleted! +static std::map >, + SCEVCommutativeExpr*> SCEVCommExprs; + +SCEVCommutativeExpr::~SCEVCommutativeExpr() { + SCEVCommExprs.erase(std::make_pair(getSCEVType(), + std::vector(Operands.begin(), + Operands.end()))); +} + +void SCEVCommutativeExpr::print(std::ostream &OS) const { + assert(Operands.size() > 1 && "This plus expr shouldn't exist!"); + const char *OpStr = getOperationStr(); + OS << "(" << *Operands[0]; + for (unsigned i = 1, e = Operands.size(); i != e; ++i) + OS << OpStr << *Operands[i]; + OS << ")"; +} + +// SCEVUDivs - Only allow the creation of one SCEVUDivExpr for any particular +// input. Don't use a SCEVHandle here, or else the object will never be +// deleted! +static std::map, SCEVUDivExpr*> SCEVUDivs; + +SCEVUDivExpr::~SCEVUDivExpr() { + SCEVUDivs.erase(std::make_pair(LHS, RHS)); +} + +void SCEVUDivExpr::print(std::ostream &OS) const { + OS << "(" << *LHS << " /u " << *RHS << ")"; +} + +const Type *SCEVUDivExpr::getType() const { + const Type *Ty = LHS->getType(); + if (Ty->isSigned()) Ty = Ty->getUnsignedVersion(); + return Ty; +} + +// SCEVAddRecExprs - Only allow the creation of one SCEVAddRecExpr for any +// particular input. Don't use a SCEVHandle here, or else the object will never +// be deleted! +static std::map >, + SCEVAddRecExpr*> SCEVAddRecExprs; + +SCEVAddRecExpr::~SCEVAddRecExpr() { + SCEVAddRecExprs.erase(std::make_pair(L, + std::vector(Operands.begin(), + Operands.end()))); +} + +bool SCEVAddRecExpr::isLoopInvariant(const Loop *QueryLoop) const { + // This recurrence is invariant w.r.t to QueryLoop iff QueryLoop doesn't + // contain L. + return !QueryLoop->contains(L->getHeader()); } -//===----------------------------------------------------------------------===// -// SCEVTruncateExpr - This class represents a truncation of an integer value to -// a smaller integer value. -// -namespace { - class SCEVTruncateExpr; - // SCEVTruncates - Only allow the creation of one SCEVTruncateExpr for any - // particular input. Don't use a SCEVHandle here, or else the object will - // never be deleted! - std::map, SCEVTruncateExpr*> SCEVTruncates; +void SCEVAddRecExpr::print(std::ostream &OS) const { + OS << "{" << *Operands[0]; + for (unsigned i = 1, e = Operands.size(); i != e; ++i) + OS << ",+," << *Operands[i]; + OS << "}<" << L->getHeader()->getName() + ">"; +} - class SCEVTruncateExpr : public SCEV { - SCEVHandle Op; - const Type *Ty; - SCEVTruncateExpr(const SCEVHandle &op, const Type *ty) - : SCEV(scTruncate), Op(op), Ty(ty) { - assert(Op->getType()->isInteger() && Ty->isInteger() && - Ty->isUnsigned() && - "Cannot truncate non-integer value!"); - assert(Op->getType()->getPrimitiveSize() > Ty->getPrimitiveSize() && - "This is not a truncating conversion!"); - } +// SCEVUnknowns - Only allow the creation of one SCEVUnknown for any particular +// value. Don't use a SCEVHandle here, or else the object will never be +// deleted! +static std::map SCEVUnknowns; - virtual ~SCEVTruncateExpr() { - SCEVTruncates.erase(std::make_pair(Op, Ty)); - } - public: - /// get method - This just gets and returns a new SCEVTruncate object - /// - static SCEVHandle get(const SCEVHandle &Op, const Type *Ty); +SCEVUnknown::~SCEVUnknown() { SCEVUnknowns.erase(V); } - const SCEVHandle &getOperand() const { return Op; } - virtual const Type *getType() const { return Ty; } - - virtual bool isLoopInvariant(const Loop *L) const { - return Op->isLoopInvariant(L); - } +bool SCEVUnknown::isLoopInvariant(const Loop *L) const { + // All non-instruction values are loop invariant. All instructions are loop + // invariant if they are not contained in the specified loop. + if (Instruction *I = dyn_cast(V)) + return !L->contains(I->getParent()); + return true; +} - virtual bool hasComputableLoopEvolution(const Loop *L) const { - return Op->hasComputableLoopEvolution(L); - } +const Type *SCEVUnknown::getType() const { + return V->getType(); +} - /// getValueRange - Return the tightest constant bounds that this value is - /// known to have. This method is only valid on integer SCEV objects. - virtual ConstantRange getValueRange() const { - return getOperand()->getValueRange().truncate(getType()); - } - - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt); - - virtual void print(std::ostream &OS) const { - OS << "(truncate " << *Op << " to " << *Ty << ")"; - } - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVTruncateExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scTruncate; - } - }; +void SCEVUnknown::print(std::ostream &OS) const { + WriteAsOperand(OS, V, false); } -//===----------------------------------------------------------------------===// -// SCEVZeroExtendExpr - This class represents a zero extension of a small -// integer value to a larger integer value. -// -namespace { - class SCEVZeroExtendExpr; - // SCEVZeroExtends - Only allow the creation of one SCEVZeroExtendExpr for any - // particular input. Don't use a SCEVHandle here, or else the object will - // never be deleted! - std::map, SCEVZeroExtendExpr*> SCEVZeroExtends; - - class SCEVZeroExtendExpr : public SCEV { - SCEVHandle Op; - const Type *Ty; - SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty) - : SCEV(scTruncate), Op(Op), Ty(ty) { - assert(Op->getType()->isInteger() && Ty->isInteger() && - Ty->isUnsigned() && - "Cannot zero extend non-integer value!"); - assert(Op->getType()->getPrimitiveSize() < Ty->getPrimitiveSize() && - "This is not an extending conversion!"); - } - - virtual ~SCEVZeroExtendExpr() { - SCEVZeroExtends.erase(std::make_pair(Op, Ty)); - } - public: - /// get method - This just gets and returns a new SCEVZeroExtend object - /// - static SCEVHandle get(const SCEVHandle &Op, const Type *Ty); - - const SCEVHandle &getOperand() const { return Op; } - virtual const Type *getType() const { return Ty; } - - virtual bool isLoopInvariant(const Loop *L) const { - return Op->isLoopInvariant(L); - } - - virtual bool hasComputableLoopEvolution(const Loop *L) const { - return Op->hasComputableLoopEvolution(L); - } - - /// getValueRange - Return the tightest constant bounds that this value is - /// known to have. This method is only valid on integer SCEV objects. - virtual ConstantRange getValueRange() const { - return getOperand()->getValueRange().zeroExtend(getType()); - } - - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt); - - virtual void print(std::ostream &OS) const { - OS << "(zeroextend " << *Op << " to " << *Ty << ")"; - } - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVZeroExtendExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scZeroExtend; - } - }; -} - - -//===----------------------------------------------------------------------===// -// SCEVCommutativeExpr - This node is the base class for n'ary commutative -// operators. - -namespace { - class SCEVCommutativeExpr; - // SCEVCommExprs - Only allow the creation of one SCEVCommutativeExpr for any - // particular input. Don't use a SCEVHandle here, or else the object will - // never be deleted! - std::map >, - SCEVCommutativeExpr*> SCEVCommExprs; - - class SCEVCommutativeExpr : public SCEV { - std::vector Operands; - - protected: - SCEVCommutativeExpr(enum SCEVTypes T, const std::vector &ops) - : SCEV(T) { - Operands.reserve(ops.size()); - Operands.insert(Operands.end(), ops.begin(), ops.end()); - } - - ~SCEVCommutativeExpr() { - SCEVCommExprs.erase(std::make_pair(getSCEVType(), - std::vector(Operands.begin(), - Operands.end()))); - } - - public: - unsigned getNumOperands() const { return Operands.size(); } - const SCEVHandle &getOperand(unsigned i) const { - assert(i < Operands.size() && "Operand index out of range!"); - return Operands[i]; - } - - const std::vector &getOperands() const { return Operands; } - typedef std::vector::const_iterator op_iterator; - op_iterator op_begin() const { return Operands.begin(); } - op_iterator op_end() const { return Operands.end(); } - - - virtual bool isLoopInvariant(const Loop *L) const { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (!getOperand(i)->isLoopInvariant(L)) return false; - return true; - } - - virtual bool hasComputableLoopEvolution(const Loop *L) const { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (getOperand(i)->hasComputableLoopEvolution(L)) return true; - return false; - } - - virtual const Type *getType() const { return getOperand(0)->getType(); } - - virtual const char *getOperationStr() const = 0; - - virtual void print(std::ostream &OS) const { - assert(Operands.size() > 1 && "This plus expr shouldn't exist!"); - const char *OpStr = getOperationStr(); - OS << "(" << *Operands[0]; - for (unsigned i = 1, e = Operands.size(); i != e; ++i) - OS << OpStr << *Operands[i]; - OS << ")"; - } - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVCommutativeExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scAddExpr || - S->getSCEVType() == scMulExpr; - } - }; -} - -//===----------------------------------------------------------------------===// -// SCEVAddExpr - This node represents an addition of some number of SCEV's. -// -namespace { - class SCEVAddExpr : public SCEVCommutativeExpr { - SCEVAddExpr(const std::vector &ops) - : SCEVCommutativeExpr(scAddExpr, ops) { - } - - public: - static SCEVHandle get(std::vector &Ops); - - static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS) { - std::vector Ops; - Ops.push_back(LHS); - Ops.push_back(RHS); - return get(Ops); - } - - static SCEVHandle get(const SCEVHandle &Op0, const SCEVHandle &Op1, - const SCEVHandle &Op2) { - std::vector Ops; - Ops.push_back(Op0); - Ops.push_back(Op1); - Ops.push_back(Op2); - return get(Ops); - } - - virtual const char *getOperationStr() const { return " + "; } - - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt); - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVAddExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scAddExpr; - } - }; -} - -//===----------------------------------------------------------------------===// -// SCEVMulExpr - This node represents multiplication of some number of SCEV's. -// -namespace { - class SCEVMulExpr : public SCEVCommutativeExpr { - SCEVMulExpr(const std::vector &ops) - : SCEVCommutativeExpr(scMulExpr, ops) { - } - - public: - static SCEVHandle get(std::vector &Ops); - - static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS) { - std::vector Ops; - Ops.push_back(LHS); - Ops.push_back(RHS); - return get(Ops); - } - - virtual const char *getOperationStr() const { return " * "; } - - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt); - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVMulExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scMulExpr; - } - }; -} - - -//===----------------------------------------------------------------------===// -// SCEVUDivExpr - This class represents a binary unsigned division operation. -// -namespace { - class SCEVUDivExpr; - // SCEVUDivs - Only allow the creation of one SCEVUDivExpr for any particular - // input. Don't use a SCEVHandle here, or else the object will never be - // deleted! - std::map, SCEVUDivExpr*> SCEVUDivs; - - class SCEVUDivExpr : public SCEV { - SCEVHandle LHS, RHS; - SCEVUDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs) - : SCEV(scUDivExpr), LHS(lhs), RHS(rhs) {} - - virtual ~SCEVUDivExpr() { - SCEVUDivs.erase(std::make_pair(LHS, RHS)); - } - public: - /// get method - This just gets and returns a new SCEVUDiv object. - /// - static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS); - - const SCEVHandle &getLHS() const { return LHS; } - const SCEVHandle &getRHS() const { return RHS; } - - virtual bool isLoopInvariant(const Loop *L) const { - return LHS->isLoopInvariant(L) && RHS->isLoopInvariant(L); - } - - virtual bool hasComputableLoopEvolution(const Loop *L) const { - return LHS->hasComputableLoopEvolution(L) && - RHS->hasComputableLoopEvolution(L); - } - - virtual const Type *getType() const { - const Type *Ty = LHS->getType(); - if (Ty->isSigned()) Ty = Ty->getUnsignedVersion(); - return Ty; - } - - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt); - - virtual void print(std::ostream &OS) const { - OS << "(" << *LHS << " /u " << *RHS << ")"; - } - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVUDivExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scUDivExpr; - } - }; -} - - -//===----------------------------------------------------------------------===// - -// SCEVAddRecExpr - This node represents a polynomial recurrence on the trip -// count of the specified loop. -// -// All operands of an AddRec are required to be loop invariant. -// -namespace { - class SCEVAddRecExpr; - // SCEVAddRecExprs - Only allow the creation of one SCEVAddRecExpr for any - // particular input. Don't use a SCEVHandle here, or else the object will - // never be deleted! - std::map >, - SCEVAddRecExpr*> SCEVAddRecExprs; - - class SCEVAddRecExpr : public SCEV { - std::vector Operands; - const Loop *L; - - SCEVAddRecExpr(const std::vector &ops, const Loop *l) - : SCEV(scAddRecExpr), Operands(ops), L(l) { - for (unsigned i = 0, e = Operands.size(); i != e; ++i) - assert(Operands[i]->isLoopInvariant(l) && - "Operands of AddRec must be loop-invariant!"); - } - ~SCEVAddRecExpr() { - SCEVAddRecExprs.erase(std::make_pair(L, - std::vector(Operands.begin(), - Operands.end()))); - } - public: - static SCEVHandle get(const SCEVHandle &Start, const SCEVHandle &Step, - const Loop *); - static SCEVHandle get(std::vector &Operands, - const Loop *); - static SCEVHandle get(const std::vector &Operands, - const Loop *L) { - std::vector NewOp(Operands); - return get(NewOp, L); - } - - typedef std::vector::const_iterator op_iterator; - op_iterator op_begin() const { return Operands.begin(); } - op_iterator op_end() const { return Operands.end(); } - - unsigned getNumOperands() const { return Operands.size(); } - const SCEVHandle &getOperand(unsigned i) const { return Operands[i]; } - const SCEVHandle &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. - SCEVHandle getStepRecurrence() const { - if (getNumOperands() == 2) return getOperand(1); - return SCEVAddRecExpr::get(std::vector(op_begin()+1,op_end()), - getLoop()); - } - - virtual bool hasComputableLoopEvolution(const Loop *QL) const { - if (L == QL) return true; - /// FIXME: What if the start or step value a recurrence for the specified - /// loop? - return false; - } - - - virtual bool isLoopInvariant(const Loop *QueryLoop) const { - // This recurrence is invariant w.r.t to QueryLoop iff QueryLoop doesn't - // contain L. - return !QueryLoop->contains(L->getHeader()); - } - - virtual const Type *getType() const { return Operands[0]->getType(); } - - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt); - - - /// isAffine - Return true if this is an affine AddRec (i.e., it represents - /// an expressions 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 is an quadratic AddRec (i.e., it - /// represents an expressions 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; - } - - /// evaluateAtIteration - Return the value of this chain of recurrences at - /// the specified iteration number. - SCEVHandle evaluateAtIteration(SCEVHandle It) 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. - SCEVHandle getNumIterationsInRange(ConstantRange Range) const; - - - virtual void print(std::ostream &OS) const { - OS << "{" << *Operands[0]; - for (unsigned i = 1, e = Operands.size(); i != e; ++i) - OS << ",+," << *Operands[i]; - OS << "}<" << L->getHeader()->getName() + ">"; - } - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVAddRecExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scAddRecExpr; - } - }; -} - - -//===----------------------------------------------------------------------===// -// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV -// value, and only represent it as it's LLVM Value. This is the "bottom" value -// for the analysis. -// -namespace { - class SCEVUnknown; - // SCEVUnknowns - Only allow the creation of one SCEVUnknown for any - // particular value. Don't use a SCEVHandle here, or else the object will - // never be deleted! - std::map SCEVUnknowns; - - class SCEVUnknown : public SCEV { - Value *V; - SCEVUnknown(Value *v) : SCEV(scUnknown), V(v) {} - - protected: - ~SCEVUnknown() { SCEVUnknowns.erase(V); } - public: - /// get method - For SCEVUnknown, this just gets and returns a new - /// SCEVUnknown. - static SCEVHandle get(Value *V) { - if (ConstantInt *CI = dyn_cast(V)) - return SCEVConstant::get(CI); - SCEVUnknown *&Result = SCEVUnknowns[V]; - if (Result == 0) Result = new SCEVUnknown(V); - return Result; - } - - Value *getValue() const { return V; } - - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt) { - return V; - } - - virtual bool isLoopInvariant(const Loop *L) const { - // All non-instruction values are loop invariant. All instructions are - // loop invariant if they are not contained in the specified loop. - if (Instruction *I = dyn_cast(V)) - return !L->contains(I->getParent()); - return true; - } - - virtual bool hasComputableLoopEvolution(const Loop *QL) const { - return false; // not computable - } - - virtual const Type *getType() const { return V->getType(); } - - virtual void print(std::ostream &OS) const { - WriteAsOperand(OS, V, false); - } - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVUnknown *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scUnknown; - } - }; -} //===----------------------------------------------------------------------===// // Simple SCEV method implementations @@ -1375,6 +956,14 @@ SCEVHandle SCEVAddRecExpr::get(std::vector &Operands, return Result; } +SCEVHandle SCEVUnknown::get(Value *V) { + if (ConstantInt *CI = dyn_cast(V)) + return SCEVConstant::get(CI); + SCEVUnknown *&Result = SCEVUnknowns[V]; + if (Result == 0) Result = new SCEVUnknown(V); + return Result; +} + //===----------------------------------------------------------------------===// // Non-trivial closed-form SCEV Expanders