diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 548f8f6ad7d..cb4d7c140d7 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -104,6 +104,10 @@ namespace llvm { /// the specified basic block. virtual bool dominates(BasicBlock *BB, DominatorTree *DT) const = 0; + /// properlyDominates - Return true if elements that makes up this SCEV + /// properly dominate the specified basic block. + virtual bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const = 0; + /// print - Print out the internal representation of this scalar to the /// specified stream. This should really only be used for debugging /// purposes. @@ -138,6 +142,10 @@ namespace llvm { return true; } + virtual bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const { + return true; + } + /// 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); diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index 33cd2a5c3ce..67f5e06977c 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -60,6 +60,10 @@ namespace llvm { 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: @@ -98,6 +102,8 @@ namespace llvm { 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) { @@ -224,6 +230,8 @@ namespace llvm { bool dominates(BasicBlock *BB, DominatorTree *DT) const; + bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const; + virtual const Type *getType() const { return getOperand(0)->getType(); } /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -337,6 +345,8 @@ namespace llvm { 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; @@ -513,6 +523,10 @@ namespace llvm { return true; } + bool properlyDominates(BasicBlock *, DominatorTree *) const { + return true; + } + virtual const Type *getType() const { return Ty; } /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -599,6 +613,8 @@ namespace llvm { 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; diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index fa452358c8d..12ad4297ef6 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -207,6 +207,10 @@ bool SCEVCastExpr::dominates(BasicBlock *BB, DominatorTree *DT) const { return Op->dominates(BB, DT); } +bool SCEVCastExpr::properlyDominates(BasicBlock *BB, DominatorTree *DT) const { + return Op->properlyDominates(BB, DT); +} + SCEVTruncateExpr::SCEVTruncateExpr(const FoldingSetNodeID &ID, const SCEV *op, const Type *ty) : SCEVCastExpr(ID, scTruncate, op, ty) { @@ -260,10 +264,22 @@ bool SCEVNAryExpr::dominates(BasicBlock *BB, DominatorTree *DT) const { return true; } +bool SCEVNAryExpr::properlyDominates(BasicBlock *BB, DominatorTree *DT) const { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + if (!getOperand(i)->properlyDominates(BB, DT)) + return false; + } + return true; +} + bool SCEVUDivExpr::dominates(BasicBlock *BB, DominatorTree *DT) const { return LHS->dominates(BB, DT) && RHS->dominates(BB, DT); } +bool SCEVUDivExpr::properlyDominates(BasicBlock *BB, DominatorTree *DT) const { + return LHS->properlyDominates(BB, DT) && RHS->properlyDominates(BB, DT); +} + void SCEVUDivExpr::print(raw_ostream &OS) const { OS << "(" << *LHS << " /u " << *RHS << ")"; } @@ -328,6 +344,12 @@ bool SCEVUnknown::dominates(BasicBlock *BB, DominatorTree *DT) const { return true; } +bool SCEVUnknown::properlyDominates(BasicBlock *BB, DominatorTree *DT) const { + if (Instruction *I = dyn_cast(getValue())) + return DT->properlyDominates(I->getParent(), BB); + return true; +} + const Type *SCEVUnknown::getType() const { return V->getType(); }