mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-30 06:40:53 +00:00
Make SCEV::getType() and SCEV::print non-virtual. Move SCEV::hasOperand
to ScalarEvolution. Delete SCEV::~SCEV. SCEV is no longer virtual. llvm-svn: 119578
This commit is contained in:
parent
ea6ac4cdff
commit
fb6ea18d0a
@ -70,8 +70,7 @@ namespace llvm {
|
||||
private:
|
||||
SCEV(const SCEV &); // DO NOT IMPLEMENT
|
||||
void operator=(const SCEV &); // DO NOT IMPLEMENT
|
||||
protected:
|
||||
virtual ~SCEV();
|
||||
|
||||
public:
|
||||
explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy) :
|
||||
FastID(ID), SCEVType(SCEVTy), SubclassData(0) {}
|
||||
@ -80,7 +79,7 @@ namespace llvm {
|
||||
|
||||
/// getType - Return the LLVM type of this SCEV expression.
|
||||
///
|
||||
virtual const Type *getType() const = 0;
|
||||
const Type *getType() const;
|
||||
|
||||
/// isZero - Return true if the expression is a constant zero.
|
||||
///
|
||||
@ -95,14 +94,10 @@ namespace llvm {
|
||||
///
|
||||
bool isAllOnesValue() const;
|
||||
|
||||
/// hasOperand - Test whether this SCEV has Op as a direct or
|
||||
/// indirect operand.
|
||||
virtual bool hasOperand(const SCEV *Op) const = 0;
|
||||
|
||||
/// print - Print out the internal representation of this scalar to the
|
||||
/// specified stream. This should really only be used for debugging
|
||||
/// purposes.
|
||||
virtual void print(raw_ostream &OS) const = 0;
|
||||
void print(raw_ostream &OS) const;
|
||||
|
||||
/// dump - This method is used for debugging.
|
||||
///
|
||||
@ -137,11 +132,6 @@ namespace llvm {
|
||||
struct SCEVCouldNotCompute : public SCEV {
|
||||
SCEVCouldNotCompute();
|
||||
|
||||
// None of these methods are valid for this object.
|
||||
virtual const Type *getType() const;
|
||||
virtual void print(raw_ostream &OS) const;
|
||||
virtual bool hasOperand(const SCEV *Op) const;
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SCEVCouldNotCompute *S) { return true; }
|
||||
static bool classof(const SCEV *S);
|
||||
@ -691,6 +681,10 @@ namespace llvm {
|
||||
/// properly dominate the specified basic block.
|
||||
bool properlyDominates(const SCEV *S, BasicBlock *BB) const;
|
||||
|
||||
/// hasOperand - Test whether the given SCEV has Op as a direct or
|
||||
/// indirect operand.
|
||||
bool hasOperand(const SCEV *S, const SCEV *Op) const;
|
||||
|
||||
virtual bool runOnFunction(Function &F);
|
||||
virtual void releaseMemory();
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
|
@ -42,13 +42,7 @@ namespace llvm {
|
||||
public:
|
||||
ConstantInt *getValue() const { return V; }
|
||||
|
||||
virtual const Type *getType() const;
|
||||
|
||||
virtual bool hasOperand(const SCEV *) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS) const;
|
||||
const Type *getType() const { return V->getType(); }
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SCEVConstant *S) { return true; }
|
||||
@ -70,11 +64,7 @@ namespace llvm {
|
||||
|
||||
public:
|
||||
const SCEV *getOperand() const { return Op; }
|
||||
virtual const Type *getType() const { return Ty; }
|
||||
|
||||
virtual bool hasOperand(const SCEV *O) const {
|
||||
return Op == O || Op->hasOperand(O);
|
||||
}
|
||||
const Type *getType() const { return Ty; }
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SCEVCastExpr *S) { return true; }
|
||||
@ -96,8 +86,6 @@ namespace llvm {
|
||||
const SCEV *op, const Type *ty);
|
||||
|
||||
public:
|
||||
virtual void print(raw_ostream &OS) const;
|
||||
|
||||
/// 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) {
|
||||
@ -116,8 +104,6 @@ namespace llvm {
|
||||
const SCEV *op, const Type *ty);
|
||||
|
||||
public:
|
||||
virtual void print(raw_ostream &OS) const;
|
||||
|
||||
/// 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) {
|
||||
@ -136,8 +122,6 @@ namespace llvm {
|
||||
const SCEV *op, const Type *ty);
|
||||
|
||||
public:
|
||||
virtual void print(raw_ostream &OS) const;
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SCEVSignExtendExpr *S) { return true; }
|
||||
static inline bool classof(const SCEV *S) {
|
||||
@ -174,9 +158,7 @@ namespace llvm {
|
||||
op_iterator op_begin() const { return Operands; }
|
||||
op_iterator op_end() const { return Operands + NumOperands; }
|
||||
|
||||
virtual bool hasOperand(const SCEV *O) const;
|
||||
|
||||
virtual const Type *getType() const { return getOperand(0)->getType(); }
|
||||
const Type *getType() const { return getOperand(0)->getType(); }
|
||||
|
||||
bool hasNoUnsignedWrap() const { return SubclassData & (1 << 0); }
|
||||
void setHasNoUnsignedWrap(bool B) {
|
||||
@ -209,10 +191,6 @@ namespace llvm {
|
||||
: SCEVNAryExpr(ID, T, O, N) {}
|
||||
|
||||
public:
|
||||
virtual const char *getOperationStr() const = 0;
|
||||
|
||||
virtual void print(raw_ostream &OS) const;
|
||||
|
||||
/// 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) {
|
||||
@ -236,9 +214,7 @@ namespace llvm {
|
||||
}
|
||||
|
||||
public:
|
||||
virtual const char *getOperationStr() const { return " + "; }
|
||||
|
||||
virtual const Type *getType() const {
|
||||
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.
|
||||
@ -264,8 +240,6 @@ namespace llvm {
|
||||
}
|
||||
|
||||
public:
|
||||
virtual const char *getOperationStr() const { return " * "; }
|
||||
|
||||
/// 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) {
|
||||
@ -289,14 +263,15 @@ namespace llvm {
|
||||
const SCEV *getLHS() const { return LHS; }
|
||||
const SCEV *getRHS() const { return RHS; }
|
||||
|
||||
virtual bool hasOperand(const SCEV *O) const {
|
||||
return O == LHS || O == RHS || LHS->hasOperand(O) || RHS->hasOperand(O);
|
||||
const Type *getType() const {
|
||||
// In most cases the types of LHS and RHS will be the same, but in some
|
||||
// crazy cases one or the other may be a pointer. ScalarEvolution doesn't
|
||||
// depend on the type for correctness, but handling types carefully can
|
||||
// avoid extra casts in the SCEVExpander. The LHS is more likely to be
|
||||
// a pointer type than the RHS, so use the RHS' type here.
|
||||
return getRHS()->getType();
|
||||
}
|
||||
|
||||
virtual const Type *getType() const;
|
||||
|
||||
void print(raw_ostream &OS) const;
|
||||
|
||||
/// 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) {
|
||||
@ -371,8 +346,6 @@ namespace llvm {
|
||||
return cast<SCEVAddRecExpr>(SE.getAddExpr(this, getStepRecurrence(SE)));
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS) const;
|
||||
|
||||
/// 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) {
|
||||
@ -396,8 +369,6 @@ namespace llvm {
|
||||
}
|
||||
|
||||
public:
|
||||
virtual const char *getOperationStr() const { return " smax "; }
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SCEVSMaxExpr *S) { return true; }
|
||||
static inline bool classof(const SCEV *S) {
|
||||
@ -421,8 +392,6 @@ namespace llvm {
|
||||
}
|
||||
|
||||
public:
|
||||
virtual const char *getOperationStr() const { return " umax "; }
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SCEVUMaxExpr *S) { return true; }
|
||||
static inline bool classof(const SCEV *S) {
|
||||
@ -468,13 +437,7 @@ namespace llvm {
|
||||
bool isAlignOf(const Type *&AllocTy) const;
|
||||
bool isOffsetOf(const Type *&STy, Constant *&FieldNo) const;
|
||||
|
||||
virtual bool hasOperand(const SCEV *) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual const Type *getType() const;
|
||||
|
||||
virtual void print(raw_ostream &OS) const;
|
||||
const Type *getType() const { return getValPtr()->getType(); }
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SCEVUnknown *S) { return true; }
|
||||
|
@ -120,13 +120,135 @@ char ScalarEvolution::ID = 0;
|
||||
// Implementation of the SCEV class.
|
||||
//
|
||||
|
||||
SCEV::~SCEV() {}
|
||||
|
||||
void SCEV::dump() const {
|
||||
print(dbgs());
|
||||
dbgs() << '\n';
|
||||
}
|
||||
|
||||
void SCEV::print(raw_ostream &OS) const {
|
||||
switch (getSCEVType()) {
|
||||
case scConstant:
|
||||
WriteAsOperand(OS, cast<SCEVConstant>(this)->getValue(), false);
|
||||
return;
|
||||
case scTruncate: {
|
||||
const SCEVTruncateExpr *Trunc = cast<SCEVTruncateExpr>(this);
|
||||
const SCEV *Op = Trunc->getOperand();
|
||||
OS << "(trunc " << *Op->getType() << " " << *Op << " to "
|
||||
<< *Trunc->getType() << ")";
|
||||
return;
|
||||
}
|
||||
case scZeroExtend: {
|
||||
const SCEVZeroExtendExpr *ZExt = cast<SCEVZeroExtendExpr>(this);
|
||||
const SCEV *Op = ZExt->getOperand();
|
||||
OS << "(zext " << *Op->getType() << " " << *Op << " to "
|
||||
<< *ZExt->getType() << ")";
|
||||
return;
|
||||
}
|
||||
case scSignExtend: {
|
||||
const SCEVSignExtendExpr *SExt = cast<SCEVSignExtendExpr>(this);
|
||||
const SCEV *Op = SExt->getOperand();
|
||||
OS << "(sext " << *Op->getType() << " " << *Op << " to "
|
||||
<< *SExt->getType() << ")";
|
||||
return;
|
||||
}
|
||||
case scAddRecExpr: {
|
||||
const SCEVAddRecExpr *AR = cast<SCEVAddRecExpr>(this);
|
||||
OS << "{" << *AR->getOperand(0);
|
||||
for (unsigned i = 1, e = AR->getNumOperands(); i != e; ++i)
|
||||
OS << ",+," << *AR->getOperand(i);
|
||||
OS << "}<";
|
||||
WriteAsOperand(OS, AR->getLoop()->getHeader(), /*PrintType=*/false);
|
||||
OS << ">";
|
||||
return;
|
||||
}
|
||||
case scAddExpr:
|
||||
case scMulExpr:
|
||||
case scUMaxExpr:
|
||||
case scSMaxExpr: {
|
||||
const SCEVNAryExpr *NAry = cast<SCEVNAryExpr>(this);
|
||||
const char *OpStr;
|
||||
switch (NAry->getSCEVType()) {
|
||||
case scAddExpr: OpStr = " + "; break;
|
||||
case scMulExpr: OpStr = " * "; break;
|
||||
case scUMaxExpr: OpStr = " umax "; break;
|
||||
case scSMaxExpr: OpStr = " smax "; break;
|
||||
}
|
||||
OS << "(";
|
||||
for (SCEVNAryExpr::op_iterator I = NAry->op_begin(), E = NAry->op_end();
|
||||
I != E; ++I) {
|
||||
OS << **I;
|
||||
if (llvm::next(I) != E)
|
||||
OS << OpStr;
|
||||
}
|
||||
OS << ")";
|
||||
return;
|
||||
}
|
||||
case scUDivExpr: {
|
||||
const SCEVUDivExpr *UDiv = cast<SCEVUDivExpr>(this);
|
||||
OS << "(" << *UDiv->getLHS() << " /u " << *UDiv->getRHS() << ")";
|
||||
return;
|
||||
}
|
||||
case scUnknown: {
|
||||
const SCEVUnknown *U = cast<SCEVUnknown>(this);
|
||||
const Type *AllocTy;
|
||||
if (U->isSizeOf(AllocTy)) {
|
||||
OS << "sizeof(" << *AllocTy << ")";
|
||||
return;
|
||||
}
|
||||
if (U->isAlignOf(AllocTy)) {
|
||||
OS << "alignof(" << *AllocTy << ")";
|
||||
return;
|
||||
}
|
||||
|
||||
const Type *CTy;
|
||||
Constant *FieldNo;
|
||||
if (U->isOffsetOf(CTy, FieldNo)) {
|
||||
OS << "offsetof(" << *CTy << ", ";
|
||||
WriteAsOperand(OS, FieldNo, false);
|
||||
OS << ")";
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise just print it normally.
|
||||
WriteAsOperand(OS, U->getValue(), false);
|
||||
return;
|
||||
}
|
||||
case scCouldNotCompute:
|
||||
OS << "***COULDNOTCOMPUTE***";
|
||||
return;
|
||||
default: break;
|
||||
}
|
||||
llvm_unreachable("Unknown SCEV kind!");
|
||||
}
|
||||
|
||||
const Type *SCEV::getType() const {
|
||||
switch (getSCEVType()) {
|
||||
case scConstant:
|
||||
return cast<SCEVConstant>(this)->getType();
|
||||
case scTruncate:
|
||||
case scZeroExtend:
|
||||
case scSignExtend:
|
||||
return cast<SCEVCastExpr>(this)->getType();
|
||||
case scAddRecExpr:
|
||||
case scMulExpr:
|
||||
case scUMaxExpr:
|
||||
case scSMaxExpr:
|
||||
return cast<SCEVNAryExpr>(this)->getType();
|
||||
case scAddExpr:
|
||||
return cast<SCEVAddExpr>(this)->getType();
|
||||
case scUDivExpr:
|
||||
return cast<SCEVUDivExpr>(this)->getType();
|
||||
case scUnknown:
|
||||
return cast<SCEVUnknown>(this)->getType();
|
||||
case scCouldNotCompute:
|
||||
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
|
||||
return 0;
|
||||
default: break;
|
||||
}
|
||||
llvm_unreachable("Unknown SCEV kind!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SCEV::isZero() const {
|
||||
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(this))
|
||||
return SC->getValue()->isZero();
|
||||
@ -148,20 +270,6 @@ bool SCEV::isAllOnesValue() const {
|
||||
SCEVCouldNotCompute::SCEVCouldNotCompute() :
|
||||
SCEV(FoldingSetNodeIDRef(), scCouldNotCompute) {}
|
||||
|
||||
const Type *SCEVCouldNotCompute::getType() const {
|
||||
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SCEVCouldNotCompute::hasOperand(const SCEV *) const {
|
||||
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
void SCEVCouldNotCompute::print(raw_ostream &OS) const {
|
||||
OS << "***COULDNOTCOMPUTE***";
|
||||
}
|
||||
|
||||
bool SCEVCouldNotCompute::classof(const SCEV *S) {
|
||||
return S->getSCEVType() == scCouldNotCompute;
|
||||
}
|
||||
@ -187,12 +295,6 @@ ScalarEvolution::getConstant(const Type *Ty, uint64_t V, bool isSigned) {
|
||||
return getConstant(ConstantInt::get(ITy, V, isSigned));
|
||||
}
|
||||
|
||||
const Type *SCEVConstant::getType() const { return V->getType(); }
|
||||
|
||||
void SCEVConstant::print(raw_ostream &OS) const {
|
||||
WriteAsOperand(OS, V, false);
|
||||
}
|
||||
|
||||
SCEVCastExpr::SCEVCastExpr(const FoldingSetNodeIDRef ID,
|
||||
unsigned SCEVTy, const SCEV *op, const Type *ty)
|
||||
: SCEV(ID, SCEVTy), Op(op), Ty(ty) {}
|
||||
@ -205,10 +307,6 @@ SCEVTruncateExpr::SCEVTruncateExpr(const FoldingSetNodeIDRef ID,
|
||||
"Cannot truncate non-integer value!");
|
||||
}
|
||||
|
||||
void SCEVTruncateExpr::print(raw_ostream &OS) const {
|
||||
OS << "(trunc " << *Op->getType() << " " << *Op << " to " << *Ty << ")";
|
||||
}
|
||||
|
||||
SCEVZeroExtendExpr::SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID,
|
||||
const SCEV *op, const Type *ty)
|
||||
: SCEVCastExpr(ID, scZeroExtend, op, ty) {
|
||||
@ -217,10 +315,6 @@ SCEVZeroExtendExpr::SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID,
|
||||
"Cannot zero extend non-integer value!");
|
||||
}
|
||||
|
||||
void SCEVZeroExtendExpr::print(raw_ostream &OS) const {
|
||||
OS << "(zext " << *Op->getType() << " " << *Op << " to " << *Ty << ")";
|
||||
}
|
||||
|
||||
SCEVSignExtendExpr::SCEVSignExtendExpr(const FoldingSetNodeIDRef ID,
|
||||
const SCEV *op, const Type *ty)
|
||||
: SCEVCastExpr(ID, scSignExtend, op, ty) {
|
||||
@ -229,52 +323,6 @@ SCEVSignExtendExpr::SCEVSignExtendExpr(const FoldingSetNodeIDRef ID,
|
||||
"Cannot sign extend non-integer value!");
|
||||
}
|
||||
|
||||
void SCEVSignExtendExpr::print(raw_ostream &OS) const {
|
||||
OS << "(sext " << *Op->getType() << " " << *Op << " to " << *Ty << ")";
|
||||
}
|
||||
|
||||
void SCEVCommutativeExpr::print(raw_ostream &OS) const {
|
||||
const char *OpStr = getOperationStr();
|
||||
OS << "(";
|
||||
for (op_iterator I = op_begin(), E = op_end(); I != E; ++I) {
|
||||
OS << **I;
|
||||
if (llvm::next(I) != E)
|
||||
OS << OpStr;
|
||||
}
|
||||
OS << ")";
|
||||
}
|
||||
|
||||
bool SCEVNAryExpr::hasOperand(const SCEV *O) const {
|
||||
for (op_iterator I = op_begin(), E = op_end(); I != E; ++I) {
|
||||
const SCEV *S = *I;
|
||||
if (O == S || S->hasOperand(O))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SCEVUDivExpr::print(raw_ostream &OS) const {
|
||||
OS << "(" << *LHS << " /u " << *RHS << ")";
|
||||
}
|
||||
|
||||
const Type *SCEVUDivExpr::getType() const {
|
||||
// In most cases the types of LHS and RHS will be the same, but in some
|
||||
// crazy cases one or the other may be a pointer. ScalarEvolution doesn't
|
||||
// depend on the type for correctness, but handling types carefully can
|
||||
// avoid extra casts in the SCEVExpander. The LHS is more likely to be
|
||||
// a pointer type than the RHS, so use the RHS' type here.
|
||||
return RHS->getType();
|
||||
}
|
||||
|
||||
void SCEVAddRecExpr::print(raw_ostream &OS) const {
|
||||
OS << "{" << *Operands[0];
|
||||
for (unsigned i = 1, e = NumOperands; i != e; ++i)
|
||||
OS << ",+," << *Operands[i];
|
||||
OS << "}<";
|
||||
WriteAsOperand(OS, L->getHeader(), /*PrintType=*/false);
|
||||
OS << ">";
|
||||
}
|
||||
|
||||
void SCEVUnknown::deleted() {
|
||||
// Clear this SCEVUnknown from various maps.
|
||||
SE->ValuesAtScopes.erase(this);
|
||||
@ -303,10 +351,6 @@ void SCEVUnknown::allUsesReplacedWith(Value *New) {
|
||||
setValPtr(New);
|
||||
}
|
||||
|
||||
const Type *SCEVUnknown::getType() const {
|
||||
return getValue()->getType();
|
||||
}
|
||||
|
||||
bool SCEVUnknown::isSizeOf(const Type *&AllocTy) const {
|
||||
if (ConstantExpr *VCE = dyn_cast<ConstantExpr>(getValue()))
|
||||
if (VCE->getOpcode() == Instruction::PtrToInt)
|
||||
@ -371,30 +415,6 @@ bool SCEVUnknown::isOffsetOf(const Type *&CTy, Constant *&FieldNo) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void SCEVUnknown::print(raw_ostream &OS) const {
|
||||
const Type *AllocTy;
|
||||
if (isSizeOf(AllocTy)) {
|
||||
OS << "sizeof(" << *AllocTy << ")";
|
||||
return;
|
||||
}
|
||||
if (isAlignOf(AllocTy)) {
|
||||
OS << "alignof(" << *AllocTy << ")";
|
||||
return;
|
||||
}
|
||||
|
||||
const Type *CTy;
|
||||
Constant *FieldNo;
|
||||
if (isOffsetOf(CTy, FieldNo)) {
|
||||
OS << "offsetof(" << *CTy << ", ";
|
||||
WriteAsOperand(OS, FieldNo, false);
|
||||
OS << ")";
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise just print it normally.
|
||||
WriteAsOperand(OS, getValue(), false);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SCEV Utilities
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -2601,7 +2621,7 @@ ScalarEvolution::ForgetSymbolicName(Instruction *PN, const SCEV *SymName) {
|
||||
|
||||
// Short-circuit the def-use traversal if the symbolic name
|
||||
// ceases to appear in expressions.
|
||||
if (Old != SymName && !Old->hasOperand(SymName))
|
||||
if (Old != SymName && !hasOperand(Old, SymName))
|
||||
continue;
|
||||
|
||||
// SCEVUnknown for a PHI either means that it has an unrecognized
|
||||
@ -6092,3 +6112,45 @@ bool ScalarEvolution::properlyDominates(const SCEV *S, BasicBlock *BB) const {
|
||||
llvm_unreachable("Unknown SCEV kind!");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScalarEvolution::hasOperand(const SCEV *S, const SCEV *Op) const {
|
||||
switch (S->getSCEVType()) {
|
||||
case scConstant:
|
||||
return false;
|
||||
case scTruncate:
|
||||
case scZeroExtend:
|
||||
case scSignExtend: {
|
||||
const SCEVCastExpr *Cast = cast<SCEVCastExpr>(S);
|
||||
const SCEV *CastOp = Cast->getOperand();
|
||||
return Op == CastOp || hasOperand(CastOp, Op);
|
||||
}
|
||||
case scAddRecExpr:
|
||||
case scAddExpr:
|
||||
case scMulExpr:
|
||||
case scUMaxExpr:
|
||||
case scSMaxExpr: {
|
||||
const SCEVNAryExpr *NAry = cast<SCEVNAryExpr>(S);
|
||||
for (SCEVNAryExpr::op_iterator I = NAry->op_begin(), E = NAry->op_end();
|
||||
I != E; ++I) {
|
||||
const SCEV *NAryOp = *I;
|
||||
if (NAryOp == Op || hasOperand(NAryOp, Op))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case scUDivExpr: {
|
||||
const SCEVUDivExpr *UDiv = cast<SCEVUDivExpr>(S);
|
||||
const SCEV *LHS = UDiv->getLHS(), *RHS = UDiv->getRHS();
|
||||
return LHS == Op || hasOperand(LHS, Op) ||
|
||||
RHS == Op || hasOperand(RHS, Op);
|
||||
}
|
||||
case scUnknown:
|
||||
return false;
|
||||
case scCouldNotCompute:
|
||||
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
|
||||
return false;
|
||||
default: break;
|
||||
}
|
||||
llvm_unreachable("Unknown SCEV kind!");
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user