summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-06-27 05:16:57 +0000
committerDan Gohman <gohman@apple.com>2009-06-27 05:16:57 +0000
commitfe174b69526af9c2ce6215418bb9f8c9e3af9ba6 (patch)
tree3b6a5699ce7a706840de19e2160bd127b452deb4 /llvm/lib
parentd17366ae72b68930bb961db2067e4d4438fdcf06 (diff)
downloadbcm5719-llvm-fe174b69526af9c2ce6215418bb9f8c9e3af9ba6.tar.gz
bcm5719-llvm-fe174b69526af9c2ce6215418bb9f8c9e3af9ba6.zip
When a value is used multiple times within a single PHI, instructions
inserted to replace that value must dominate all of of the basic blocks associated with the uses of the value in the PHI, not just one of them. llvm-svn: 74376
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Scalar/IndVarSimplify.cpp18
1 files changed, 15 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
index d2ba25637e0..27e377f9037 100644
--- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -70,6 +70,7 @@ namespace {
IVUsers *IU;
LoopInfo *LI;
ScalarEvolution *SE;
+ DominatorTree *DT;
bool Changed;
public:
@@ -329,6 +330,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
IU = &getAnalysis<IVUsers>();
LI = &getAnalysis<LoopInfo>();
SE = &getAnalysis<ScalarEvolution>();
+ DT = &getAnalysis<DominatorTree>();
Changed = false;
// If there are any floating-point recurrences, attempt to
@@ -479,12 +481,22 @@ void IndVarSimplify::RewriteIVExpressions(Loop *L, const Type *LargestType,
if (!AR->isLoopInvariant(L) && !Stride->isLoopInvariant(L))
continue;
+ // Determine the insertion point for this user. By default, insert
+ // immediately before the user. The SCEVExpander class will automatically
+ // hoist loop invariants out of the loop. For PHI nodes, there may be
+ // multiple uses, so compute the nearest common dominator for the
+ // incoming blocks.
Instruction *InsertPt = User;
if (PHINode *PHI = dyn_cast<PHINode>(InsertPt))
- for (unsigned i = 0; ; ++i)
+ for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
if (PHI->getIncomingValue(i) == Op) {
- InsertPt = PHI->getIncomingBlock(i)->getTerminator();
- break;
+ if (InsertPt == User)
+ InsertPt = PHI->getIncomingBlock(i)->getTerminator();
+ else
+ InsertPt =
+ DT->findNearestCommonDominator(InsertPt->getParent(),
+ PHI->getIncomingBlock(i))
+ ->getTerminator();
}
// Now expand it into actual Instructions and patch it into place.
OpenPOWER on IntegriCloud