summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-02-17 20:49:49 +0000
committerDan Gohman <gohman@apple.com>2009-02-17 20:49:49 +0000
commit4330034160a3eb6e2cdb7590c797121554fab904 (patch)
treed4590a627df76ddb8fdc49fd7428e1e259e26393 /llvm
parent24f31a0e59873421311bbe0b16198b4e3ad0cd91 (diff)
downloadbcm5719-llvm-4330034160a3eb6e2cdb7590c797121554fab904.tar.gz
bcm5719-llvm-4330034160a3eb6e2cdb7590c797121554fab904.zip
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
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/Analysis/ScalarEvolution.h5
-rw-r--r--llvm/lib/Analysis/LoopPass.cpp3
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp16
-rw-r--r--llvm/lib/Transforms/Scalar/IndVarSimplify.cpp25
4 files changed, 37 insertions, 12 deletions
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index d94329d265b..963117fdd56 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 da9ac2749a0..c45c2ef4c0b 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<LoopInfo>();
- // Used by IndVar doInitialization.
- Info.addRequired<ScalarEvolution>();
Info.setPreservesAll();
}
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 4e0dba7e04b..54f27653542 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<SCEVCouldNotCompute>(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 dc4f10b4196..4cfe3595bee 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<ScalarEvolution>();
AU.addRequiredID(LCSSAID);
@@ -88,6 +88,8 @@ namespace {
private:
+ void RewriteNonIntegerIVs(Loop *L);
+
void EliminatePointerRecurrence(PHINode *PN, BasicBlock *Preheader,
SmallPtrSet<Instruction*, 16> &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<ScalarEvolution>();
SmallPtrSet<Instruction*, 16> DeadInsts;
for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(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<LoopInfo>();
SE = &getAnalysis<ScalarEvolution>();
-
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<Instruction*, 16> DeadInsts;
OpenPOWER on IntegriCloud