diff options
author | Owen Anderson <resistor@mac.com> | 2006-07-12 21:29:14 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2006-07-12 21:29:14 +0000 |
commit | dea9202e3b0ff7062885655c37dce906888ba2df (patch) | |
tree | f89c86db34e8ad5b27568c8781222abaad1fc19b /llvm/lib | |
parent | 5b17dee741f671440b7c799fe87a994d75271faf (diff) | |
download | bcm5719-llvm-dea9202e3b0ff7062885655c37dce906888ba2df.tar.gz bcm5719-llvm-dea9202e3b0ff7062885655c37dce906888ba2df.zip |
IndVars now (correctly) preserves LCSSA form.
llvm-svn: 29126
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 46 |
1 files changed, 31 insertions, 15 deletions
diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index a46916077ae..637932995cb 100644 --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -79,6 +79,7 @@ namespace { AU.addRequired<ScalarEvolution>(); AU.addRequired<LoopInfo>(); AU.addPreservedID(LoopSimplifyID); + AU.addPreservedID(LCSSAID); AU.setPreservesCFG(); } private: @@ -325,20 +326,8 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L) { for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) { Instruction *User = cast<Instruction>(*UI); - if (!L->contains(User->getParent())) { - // If this is a PHI node in the exit block and we're inserting, - // into the exit block, it must have a single entry. In this - // case, we can't insert the code after the PHI and have the PHI - // still use it. Instead, don't insert the the PHI. - if (PHINode *PN = dyn_cast<PHINode>(User)) { - // FIXME: This is a case where LCSSA pessimizes code, this - // should be fixed better. - if (PN->getNumOperands() == 2 && - PN->getParent() == BlockToInsertInto) - continue; - } + if (!L->contains(User->getParent())) ExtraLoopUsers.push_back(User); - } } if (!ExtraLoopUsers.empty()) { @@ -358,8 +347,35 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L) { // Rewrite any users of the computed value outside of the loop // with the newly computed value. - for (unsigned i = 0, e = ExtraLoopUsers.size(); i != e; ++i) - ExtraLoopUsers[i]->replaceUsesOfWith(I, NewVal); + for (unsigned i = 0, e = ExtraLoopUsers.size(); i != e; ++i) { + PHINode* PN = dyn_cast<PHINode>(ExtraLoopUsers[i]); + if (PN && !L->contains(PN->getParent())) { + // We're dealing with an LCSSA Phi. Handle it specially. + Instruction* LCSSAInsertPt = BlockToInsertInto->begin(); + + Instruction* NewInstr = dyn_cast<Instruction>(NewVal); + if (NewInstr && !isa<PHINode>(NewInstr) && + !L->contains(NewInstr->getParent())) + for (unsigned j = 0; j < NewInstr->getNumOperands(); ++j){ + Instruction* PredI = + dyn_cast<Instruction>(NewInstr->getOperand(j)); + if (PredI && L->contains(PredI->getParent())) { + PHINode* NewLCSSA = new PHINode(PredI->getType(), + PredI->getName() + ".lcssa", + LCSSAInsertPt); + NewLCSSA->addIncoming(PredI, + BlockToInsertInto->getSinglePredecessor()); + + NewInstr->replaceUsesOfWith(PredI, NewLCSSA); + } + } + + PN->replaceAllUsesWith(NewVal); + PN->eraseFromParent(); + } else { + ExtraLoopUsers[i]->replaceUsesOfWith(I, NewVal); + } + } // If this instruction is dead now, schedule it to be removed. if (I->use_empty()) |