From 4330034160a3eb6e2cdb7590c797121554fab904 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 17 Feb 2009 20:49:49 +0000 Subject: [PATCH] Add a method to ScalarEvolution for telling it when a loop has been modified in a way that may effect the trip count calculation. Change IndVars to use this method when it rewrites pointer or floating-point induction variables instead of using a doInitialization method to sneak these changes in before ScalarEvolution has a chance to see the loop. This eliminates the need for LoopPass to depend on ScalarEvolution. llvm-svn: 64810 --- llvm/include/llvm/Analysis/ScalarEvolution.h | 5 ++++ llvm/lib/Analysis/LoopPass.cpp | 3 --- llvm/lib/Analysis/ScalarEvolution.cpp | 16 ++++++++++++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 25 ++++++++++++------- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index d94329d265b8..963117fdd562 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -301,6 +301,11 @@ namespace llvm { /// an analyzable loop-invariant iteration count. bool hasLoopInvariantIterationCount(const Loop *L) const; + /// forgetLoopIterationCount - This method should be called by the + /// client when it has changed a loop in a way that may effect + /// ScalarEvolution's ability to compute a trip count. + void forgetLoopIterationCount(const Loop *L); + /// deleteValueFromRecords - This method should be called by the /// client before it removes a Value from the program, to make sure /// that no dangling references are left around. diff --git a/llvm/lib/Analysis/LoopPass.cpp b/llvm/lib/Analysis/LoopPass.cpp index da9ac2749a03..c45c2ef4c0bb 100644 --- a/llvm/lib/Analysis/LoopPass.cpp +++ b/llvm/lib/Analysis/LoopPass.cpp @@ -14,7 +14,6 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/LoopPass.h" -#include "llvm/Analysis/ScalarEvolution.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -173,8 +172,6 @@ void LPPassManager::getAnalysisUsage(AnalysisUsage &Info) const { // LPPassManager needs LoopInfo. In the long term LoopInfo class will // become part of LPPassManager. Info.addRequired(); - // Used by IndVar doInitialization. - Info.addRequired(); Info.setPreservesAll(); } diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 4e0dba7e04b3..54f276535421 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -1453,6 +1453,11 @@ namespace { /// an analyzable loop-invariant iteration count. bool hasLoopInvariantIterationCount(const Loop *L); + /// forgetLoopIterationCount - This method should be called by the + /// client when it has changed a loop in a way that may effect + /// ScalarEvolution's ability to compute a trip count. + void forgetLoopIterationCount(const Loop *L); + /// getIterationCount - If the specified loop has a predictable iteration /// count, return it. Note that it is not valid to call this method on a /// loop without a loop-invariant iteration count. @@ -1931,6 +1936,13 @@ SCEVHandle ScalarEvolutionsImpl::getIterationCount(const Loop *L) { return I->second; } +/// forgetLoopIterationCount - This method should be called by the +/// client when it has changed a loop in a way that may effect +/// ScalarEvolution's ability to compute a trip count. +void ScalarEvolutionsImpl::forgetLoopIterationCount(const Loop *L) { + IterationCounts.erase(L); +} + /// ComputeIterationCount - Compute the number of times the specified loop /// will iterate. SCEVHandle ScalarEvolutionsImpl::ComputeIterationCount(const Loop *L) { @@ -3091,6 +3103,10 @@ bool ScalarEvolution::hasLoopInvariantIterationCount(const Loop *L) const { return !isa(getIterationCount(L)); } +void ScalarEvolution::forgetLoopIterationCount(const Loop *L) { + return ((ScalarEvolutionsImpl*)Impl)->forgetLoopIterationCount(L); +} + SCEVHandle ScalarEvolution::getSCEVAtScope(Value *V, const Loop *L) const { return ((ScalarEvolutionsImpl*)Impl)->getSCEVAtScope(getSCEV(V), L); } diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index dc4f10b4196b..4cfe3595beea 100644 --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -74,8 +74,8 @@ namespace { static char ID; // Pass identification, replacement for typeid IndVarSimplify() : LoopPass(&ID) {} - bool runOnLoop(Loop *L, LPPassManager &LPM); - bool doInitialization(Loop *L, LPPassManager &LPM); + virtual bool runOnLoop(Loop *L, LPPassManager &LPM); + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.addRequiredID(LCSSAID); @@ -88,6 +88,8 @@ namespace { private: + void RewriteNonIntegerIVs(Loop *L); + void EliminatePointerRecurrence(PHINode *PN, BasicBlock *Preheader, SmallPtrSet &DeadInsts); void LinearFunctionTestReplace(Loop *L, SCEVHandle IterationCount, @@ -411,16 +413,13 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L, SCEV *IterationCount) { DeleteTriviallyDeadInstructions(InstructionsToDelete); } -bool IndVarSimplify::doInitialization(Loop *L, LPPassManager &LPM) { - - Changed = false; +void IndVarSimplify::RewriteNonIntegerIVs(Loop *L) { // First step. Check to see if there are any trivial GEP pointer recurrences. // If there are, change them into integer recurrences, permitting analysis by // the SCEV routines. // BasicBlock *Header = L->getHeader(); BasicBlock *Preheader = L->getLoopPreheader(); - SE = &LPM.getAnalysis(); SmallPtrSet DeadInsts; for (BasicBlock::iterator I = Header->begin(); isa(I); ++I) { @@ -431,10 +430,14 @@ bool IndVarSimplify::doInitialization(Loop *L, LPPassManager &LPM) { HandleFloatingPointIV(L, PN, DeadInsts); } + // If the loop previously had a pointer or floating-point IV, ScalarEvolution + // may not have been able to compute a trip count. Now that we've done some + // re-writing, the trip count may be computable. + if (Changed) + SE->forgetLoopIterationCount(L); + if (!DeadInsts.empty()) DeleteTriviallyDeadInstructions(DeadInsts); - - return Changed; } /// getEffectiveIndvarType - Determine the widest type that the @@ -594,8 +597,12 @@ static void TestOrigIVForWrap(const Loop *L, bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { LI = &getAnalysis(); SE = &getAnalysis(); - Changed = false; + + // If there are any floating-point or pointer recurrences, attempt to + // transform them to use integer recurrences. + RewriteNonIntegerIVs(L); + BasicBlock *Header = L->getHeader(); BasicBlock *ExitingBlock = L->getExitingBlock(); SmallPtrSet DeadInsts;