//===- llvm/Analysis/ScalarEvolutionExpressions.h - SCEV Exprs --*- C++ -*-===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file defines the classes used to represent and build scalar expressions.
-//
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
enum SCEVTypes {
// These should be ordered in terms of increasing complexity to make the
// folders simpler.
- scConstant, scTruncate, scZeroExtend, scAddExpr, scMulExpr, scUDivExpr,
+ scConstant, scTruncate, scZeroExtend, scAddExpr, scMulExpr, scSDivExpr,
scAddRecExpr, scUnknown, scCouldNotCompute
};
class SCEVConstant : public SCEV {
ConstantInt *V;
SCEVConstant(ConstantInt *v) : SCEV(scConstant), V(v) {}
-
+
virtual ~SCEVConstant();
public:
/// get method - This just gets and returns a new SCEVConstant object.
virtual const Type *getType() const;
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ return this;
+ }
+
virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVConstant *S) { return true; }
const SCEVHandle &getOperand() const { return Op; }
virtual const Type *getType() const { return Ty; }
-
+
virtual bool isLoopInvariant(const Loop *L) const {
return Op->isLoopInvariant(L);
}
return Op->hasComputableLoopEvolution(L);
}
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc);
+ if (H == Op)
+ return this;
+ return get(H, Ty);
+ }
+
/// 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;
virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVTruncateExpr *S) { return true; }
const SCEVHandle &getOperand() const { return Op; }
virtual const Type *getType() const { return Ty; }
-
+
virtual bool isLoopInvariant(const Loop *L) const {
return Op->isLoopInvariant(L);
}
/// known to have. This method is only valid on integer SCEV objects.
virtual ConstantRange getValueRange() const;
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc);
+ if (H == Op)
+ return this;
+ return get(H, Ty);
+ }
+
virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVZeroExtendExpr *S) { return true; }
return true;
}
+ // hasComputableLoopEvolution - Commutative expressions have computable loop
+ // evolutions iff they have at least one operand that varies with the loop,
+ // but that all varying operands are computable.
virtual bool hasComputableLoopEvolution(const Loop *L) const {
+ bool HasVarying = false;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- if (getOperand(i)->hasComputableLoopEvolution(L)) return true;
- return false;
+ if (!getOperand(i)->isLoopInvariant(L))
+ if (getOperand(i)->hasComputableLoopEvolution(L))
+ HasVarying = true;
+ else
+ return false;
+ return HasVarying;
}
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const;
+
virtual const char *getOperationStr() const = 0;
virtual const Type *getType() const { return getOperand(0)->getType(); }
virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVCommutativeExpr *S) { return true; }
//===--------------------------------------------------------------------===//
- /// SCEVUDivExpr - This class represents a binary unsigned division operation.
+ /// SCEVSDivExpr - This class represents a binary signed division operation.
///
- class SCEVUDivExpr : public SCEV {
+ class SCEVSDivExpr : public SCEV {
SCEVHandle LHS, RHS;
- SCEVUDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs)
- : SCEV(scUDivExpr), LHS(lhs), RHS(rhs) {}
+ SCEVSDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs)
+ : SCEV(scSDivExpr), LHS(lhs), RHS(rhs) {}
- virtual ~SCEVUDivExpr();
+ virtual ~SCEVSDivExpr();
public:
- /// get method - This just gets and returns a new SCEVUDiv object.
+ /// get method - This just gets and returns a new SCEVSDiv object.
///
static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS);
RHS->hasComputableLoopEvolution(L);
}
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ SCEVHandle L = LHS->replaceSymbolicValuesWithConcrete(Sym, Conc);
+ SCEVHandle R = RHS->replaceSymbolicValuesWithConcrete(Sym, Conc);
+ if (L == LHS && R == RHS)
+ return this;
+ else
+ return get(L, R);
+ }
+
+
virtual const Type *getType() const;
void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
/// 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 SCEVSDivExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
- return S->getSCEVType() == scUDivExpr;
+ return S->getSCEVType() == scSDivExpr;
}
};
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;
}
/// 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;
+ /// returned. The isSigned parameter indicates whether the ConstantRange
+ /// should be treated as signed or unsigned.
+ SCEVHandle getNumIterationsInRange(ConstantRange Range,
+ bool isSigned) const;
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const;
virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVAddRecExpr *S) { return true; }
return false; // not computable
}
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ if (&*Sym == this) return Conc;
+ return this;
+ }
+
virtual const Type *getType() const;
virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVUnknown *S) { return true; }
return ((SC*)this)->visitAddExpr((SCEVAddExpr*)S);
case scMulExpr:
return ((SC*)this)->visitMulExpr((SCEVMulExpr*)S);
- case scUDivExpr:
- return ((SC*)this)->visitUDivExpr((SCEVUDivExpr*)S);
+ case scSDivExpr:
+ return ((SC*)this)->visitSDivExpr((SCEVSDivExpr*)S);
case scAddRecExpr:
return ((SC*)this)->visitAddRecExpr((SCEVAddRecExpr*)S);
case scUnknown: