// These should be ordered in terms of increasing complexity to make the
// folders simpler.
scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr,
- scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr, scUnknown,
- scCouldNotCompute
+ scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr,
+ scUnknown, scCouldNotCompute
};
//===--------------------------------------------------------------------===//
virtual const Type *getType() const;
- const SCEV *replaceSymbolicValuesWithConcrete(const SCEV *Sym,
- const SCEV *Conc,
- ScalarEvolution &SE) const {
- return this;
+ virtual bool hasOperand(const SCEV *) const {
+ return false;
}
bool dominates(BasicBlock *BB, DominatorTree *DT) const {
return true;
}
+ bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const {
+ return true;
+ }
+
virtual void print(raw_ostream &OS) const;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
return Op->hasComputableLoopEvolution(L);
}
+ virtual bool hasOperand(const SCEV *O) const {
+ return Op == O || Op->hasOperand(O);
+ }
+
virtual bool dominates(BasicBlock *BB, DominatorTree *DT) const;
+ virtual bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const;
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVCastExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
const SCEV *op, const Type *ty);
public:
- const SCEV *replaceSymbolicValuesWithConcrete(const SCEV *Sym,
- const SCEV *Conc,
- ScalarEvolution &SE) const {
- const SCEV *H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
- if (H == Op)
- return this;
- return SE.getTruncateExpr(H, Ty);
- }
-
virtual void print(raw_ostream &OS) const;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
const SCEV *op, const Type *ty);
public:
- const SCEV *replaceSymbolicValuesWithConcrete(const SCEV *Sym,
- const SCEV *Conc,
- ScalarEvolution &SE) const {
- const SCEV *H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
- if (H == Op)
- return this;
- return SE.getZeroExtendExpr(H, Ty);
- }
-
virtual void print(raw_ostream &OS) const;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
const SCEV *op, const Type *ty);
public:
- const SCEV *replaceSymbolicValuesWithConcrete(const SCEV *Sym,
- const SCEV *Conc,
- ScalarEvolution &SE) const {
- const SCEV *H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
- if (H == Op)
- return this;
- return SE.getSignExtendExpr(H, Ty);
- }
-
virtual void print(raw_ostream &OS) const;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
return HasVarying;
}
+ virtual bool hasOperand(const SCEV *O) const {
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ if (O == getOperand(i) || getOperand(i)->hasOperand(O))
+ return true;
+ return false;
+ }
+
bool dominates(BasicBlock *BB, DominatorTree *DT) const;
+ bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const;
+
virtual const Type *getType() const { return getOperand(0)->getType(); }
+ bool hasNoUnsignedWrap() const { return SubclassData & (1 << 0); }
+ void setHasNoUnsignedWrap(bool B) {
+ SubclassData = (SubclassData & ~(1 << 0)) | (B << 0);
+ }
+ bool hasNoSignedWrap() const { return SubclassData & (1 << 1); }
+ void setHasNoSignedWrap(bool B) {
+ SubclassData = (SubclassData & ~(1 << 1)) | (B << 1);
+ }
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVNAryExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
: SCEVNAryExpr(ID, T, ops) {}
public:
- const SCEV *replaceSymbolicValuesWithConcrete(const SCEV *Sym,
- const SCEV *Conc,
- ScalarEvolution &SE) const;
-
virtual const char *getOperationStr() const = 0;
virtual void print(raw_ostream &OS) const;
public:
virtual const char *getOperationStr() const { return " + "; }
+ virtual const Type *getType() const {
+ // Use the type of the last operand, which is likely to be a pointer
+ // type, if there is one. This doesn't usually matter, but it can help
+ // reduce casts when the expressions are expanded.
+ return getOperand(getNumOperands() - 1)->getType();
+ }
+
/// 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) {
RHS->hasComputableLoopEvolution(L);
}
- const SCEV *replaceSymbolicValuesWithConcrete(const SCEV *Sym,
- const SCEV *Conc,
- ScalarEvolution &SE) const {
- const SCEV *L = LHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
- const SCEV *R = RHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
- if (L == LHS && R == RHS)
- return this;
- else
- return SE.getUDivExpr(L, R);
+ virtual bool hasOperand(const SCEV *O) const {
+ return O == LHS || O == RHS || LHS->hasOperand(O) || RHS->hasOperand(O);
}
bool dominates(BasicBlock *BB, DominatorTree *DT) const;
+ bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const;
+
virtual const Type *getType() const;
void print(raw_ostream &OS) const;
const SCEV *getNumIterationsInRange(ConstantRange Range,
ScalarEvolution &SE) const;
- const SCEV *replaceSymbolicValuesWithConcrete(const SCEV *Sym,
- const SCEV *Conc,
- ScalarEvolution &SE) const;
-
/// getPostIncExpr - Return an expression representing the value of
/// this expression one iteration of the loop ahead.
- const SCEV *getPostIncExpr(ScalarEvolution &SE) const {
- return SE.getAddExpr(this, getStepRecurrence(SE));
+ const SCEVAddRecExpr *getPostIncExpr(ScalarEvolution &SE) const {
+ return cast<SCEVAddRecExpr>(SE.getAddExpr(this, getStepRecurrence(SE)));
}
virtual void print(raw_ostream &OS) const;
SCEVSMaxExpr(const FoldingSetNodeID &ID,
const SmallVectorImpl<const SCEV *> &ops)
: SCEVCommutativeExpr(ID, scSMaxExpr, ops) {
+ // Max never overflows.
+ setHasNoUnsignedWrap(true);
+ setHasNoSignedWrap(true);
}
public:
SCEVUMaxExpr(const FoldingSetNodeID &ID,
const SmallVectorImpl<const SCEV *> &ops)
: SCEVCommutativeExpr(ID, scUMaxExpr, ops) {
+ // Max never overflows.
+ setHasNoUnsignedWrap(true);
+ setHasNoSignedWrap(true);
}
public:
}
};
-
//===--------------------------------------------------------------------===//
/// 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, and only represent it as its LLVM Value. This is the "bottom"
/// value for the analysis.
///
class SCEVUnknown : public SCEV {
public:
Value *getValue() const { return V; }
+ /// 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.
+ bool isSizeOf(const Type *&AllocTy) const;
+ bool isAlignOf(const Type *&AllocTy) const;
+ bool isOffsetOf(const Type *&STy, Constant *&FieldNo) const;
+
virtual bool isLoopInvariant(const Loop *L) const;
virtual bool hasComputableLoopEvolution(const Loop *QL) const {
return false; // not computable
}
- const SCEV *replaceSymbolicValuesWithConcrete(const SCEV *Sym,
- const SCEV *Conc,
- ScalarEvolution &SE) const {
- if (&*Sym == this) return Conc;
- return this;
+ virtual bool hasOperand(const SCEV *) const {
+ return false;
}
bool dominates(BasicBlock *BB, DominatorTree *DT) const;
+ bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const;
+
virtual const Type *getType() const;
virtual void print(raw_ostream &OS) const;