diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 40 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp | 13 |
2 files changed, 44 insertions, 9 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 59e76c0538f..4e0dba7e04b 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -66,6 +66,7 @@ #include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Assembly/Writer.h" #include "llvm/Transforms/Scalar.h" @@ -205,6 +206,10 @@ SCEVTruncateExpr::~SCEVTruncateExpr() { SCEVTruncates->erase(std::make_pair(Op, Ty)); } +bool SCEVTruncateExpr::dominates(BasicBlock *BB, DominatorTree *DT) const { + return Op->dominates(BB, DT); +} + void SCEVTruncateExpr::print(std::ostream &OS) const { OS << "(truncate " << *Op << " to " << *Ty << ")"; } @@ -227,6 +232,10 @@ SCEVZeroExtendExpr::~SCEVZeroExtendExpr() { SCEVZeroExtends->erase(std::make_pair(Op, Ty)); } +bool SCEVZeroExtendExpr::dominates(BasicBlock *BB, DominatorTree *DT) const { + return Op->dominates(BB, DT); +} + void SCEVZeroExtendExpr::print(std::ostream &OS) const { OS << "(zeroextend " << *Op << " to " << *Ty << ")"; } @@ -249,6 +258,10 @@ SCEVSignExtendExpr::~SCEVSignExtendExpr() { SCEVSignExtends->erase(std::make_pair(Op, Ty)); } +bool SCEVSignExtendExpr::dominates(BasicBlock *BB, DominatorTree *DT) const { + return Op->dominates(BB, DT); +} + void SCEVSignExtendExpr::print(std::ostream &OS) const { OS << "(signextend " << *Op << " to " << *Ty << ")"; } @@ -306,6 +319,14 @@ replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, return this; } +bool SCEVCommutativeExpr::dominates(BasicBlock *BB, DominatorTree *DT) const { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + if (!getOperand(i)->dominates(BB, DT)) + return false; + } + return true; +} + // 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 @@ -317,6 +338,10 @@ SCEVUDivExpr::~SCEVUDivExpr() { SCEVUDivs->erase(std::make_pair(LHS, RHS)); } +bool SCEVUDivExpr::dominates(BasicBlock *BB, DominatorTree *DT) const { + return LHS->dominates(BB, DT) && RHS->dominates(BB, DT); +} + void SCEVUDivExpr::print(std::ostream &OS) const { OS << "(" << *LHS << " /u " << *RHS << ")"; } @@ -337,6 +362,15 @@ SCEVAddRecExpr::~SCEVAddRecExpr() { Operands.end()))); } +bool SCEVAddRecExpr::dominates(BasicBlock *BB, DominatorTree *DT) const { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + if (!getOperand(i)->dominates(BB, DT)) + return false; + } + return true; +} + + SCEVHandle SCEVAddRecExpr:: replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, const SCEVHandle &Conc, @@ -391,6 +425,12 @@ bool SCEVUnknown::isLoopInvariant(const Loop *L) const { return true; } +bool SCEVUnknown::dominates(BasicBlock *BB, DominatorTree *DT) const { + if (Instruction *I = dyn_cast<Instruction>(getValue())) + return DT->dominates(I->getParent(), BB); + return true; +} + const Type *SCEVUnknown::getType() const { return V->getType(); } diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 055114c215d..0945a5759f8 100644 --- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -438,16 +438,11 @@ static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L, Start = SE->getAddExpr(Start, AddRec->getOperand(0)); if (!isa<SCEVConstant>(AddRec->getOperand(1))) { - // If stride is an instruction, make sure it dominates the loop header. + // If stride is an instruction, make sure it dominates the loop preheader. // Otherwise we could end up with a use before def situation. - if (SCEVUnknown *SU = dyn_cast<SCEVUnknown>(AddRec->getOperand(1))) { - if (Instruction *I = dyn_cast<Instruction>(SU->getValue())) { - BasicBlock *StrideBB = I->getParent(); - BasicBlock *Preheader = L->getLoopPreheader(); - if (!DT->dominates(StrideBB, Preheader)) - return false; - } - } + BasicBlock *Preheader = L->getLoopPreheader(); + if (!AddRec->getOperand(1)->dominates(Preheader, DT)) + return false; DOUT << "[" << L->getHeader()->getName() << "] Variable stride: " << *AddRec << "\n"; |

