diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-09-06 02:26:10 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-09-06 02:26:10 +0000 |
commit | 8f78a58e14fa754cde827e46ad03f00c7a6ead01 (patch) | |
tree | 1d83ef98ecaa3cd9f02b23d398f4b0adbed71ed9 /lib/Transforms/Scalar/LoopUnswitch.cpp | |
parent | 92a97a9166e359e195d949e63d7e24a4a33284cf (diff) |
Revert r80926. It causes loop unswitch assertion and slow down some JIT tests significantly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81101 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/LoopUnswitch.cpp')
-rw-r--r-- | lib/Transforms/Scalar/LoopUnswitch.cpp | 95 |
1 files changed, 62 insertions, 33 deletions
diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp index b49e14a810..8e7c91a3f2 100644 --- a/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -518,12 +518,7 @@ void LoopUnswitch::EmitPreheaderBranchOnCondition(Value *LIC, Constant *Val, std::swap(TrueDest, FalseDest); // Insert the new branch. - BranchInst *BI = BranchInst::Create(TrueDest, FalseDest, BranchVal, InsertPt); - - // If either edge is critical, split it. This helps preserve LoopSimplify - // form for enclosing loops. - SplitCriticalEdge(BI, 0, this); - SplitCriticalEdge(BI, 1, this); + BranchInst::Create(TrueDest, FalseDest, BranchVal, InsertPt); } /// UnswitchTrivialCondition - Given a loop that has a trivial unswitchable @@ -580,11 +575,47 @@ void LoopUnswitch::SplitExitEdges(Loop *L, for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) { BasicBlock *ExitBlock = ExitBlocks[i]; - SmallVector<BasicBlock *, 4> Preds(pred_begin(ExitBlock), - pred_end(ExitBlock)); - SplitBlockPredecessors(ExitBlock, Preds.data(), Preds.size(), - ".us-lcssa", this); + std::vector<BasicBlock*> Preds(pred_begin(ExitBlock), pred_end(ExitBlock)); + + for (unsigned j = 0, e = Preds.size(); j != e; ++j) { + BasicBlock* NewExitBlock = SplitEdge(Preds[j], ExitBlock, this); + BasicBlock* StartBlock = Preds[j]; + BasicBlock* EndBlock; + if (NewExitBlock->getSinglePredecessor() == ExitBlock) { + EndBlock = NewExitBlock; + NewExitBlock = EndBlock->getSinglePredecessor(); + } else { + EndBlock = ExitBlock; + } + + std::set<PHINode*> InsertedPHIs; + PHINode* OldLCSSA = 0; + for (BasicBlock::iterator I = EndBlock->begin(); + (OldLCSSA = dyn_cast<PHINode>(I)); ++I) { + Value* OldValue = OldLCSSA->getIncomingValueForBlock(NewExitBlock); + PHINode* NewLCSSA = PHINode::Create(OldLCSSA->getType(), + OldLCSSA->getName() + ".us-lcssa", + NewExitBlock->getTerminator()); + NewLCSSA->addIncoming(OldValue, StartBlock); + OldLCSSA->setIncomingValue(OldLCSSA->getBasicBlockIndex(NewExitBlock), + NewLCSSA); + InsertedPHIs.insert(NewLCSSA); + } + + BasicBlock::iterator InsertPt = EndBlock->getFirstNonPHI(); + for (BasicBlock::iterator I = NewExitBlock->begin(); + (OldLCSSA = dyn_cast<PHINode>(I)) && InsertedPHIs.count(OldLCSSA) == 0; + ++I) { + PHINode *NewLCSSA = PHINode::Create(OldLCSSA->getType(), + OldLCSSA->getName() + ".us-lcssa", + InsertPt); + OldLCSSA->replaceAllUsesWith(NewLCSSA); + NewLCSSA->addIncoming(OldLCSSA, NewExitBlock); + } + + } } + } /// UnswitchNontrivialCondition - We determined that the loop is profitable @@ -914,29 +945,27 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC, // FIXME: This is a hack. We need to keep the successor around // and hooked up so as to preserve the loop structure, because // trying to update it is complicated. So instead we preserve the - // loop structure and put the block on a dead code path. - BasicBlock *Switch = SI->getParent(); - SplitEdge(Switch, SI->getSuccessor(i), this); - // Compute the successors instead of relying on the return value - // of SplitEdge, since it may have split the switch successor - // after PHI nodes. - BasicBlock *NewSISucc = SI->getSuccessor(i); - BasicBlock *OldSISucc = *succ_begin(NewSISucc); - // Create an "unreachable" destination. - BasicBlock *Abort = BasicBlock::Create(Context, "us-unreachable", - Switch->getParent(), - OldSISucc); - new UnreachableInst(Context, Abort); - // Force the new case destination to branch to the "unreachable" - // block while maintaining a (dead) CFG edge to the old block. - NewSISucc->getTerminator()->eraseFromParent(); - BranchInst::Create(Abort, OldSISucc, - ConstantInt::getTrue(Context), NewSISucc); - // Release the PHI operands for this edge. - for (BasicBlock::iterator II = NewSISucc->begin(); - PHINode *PN = dyn_cast<PHINode>(II); ++II) - PN->setIncomingValue(PN->getBasicBlockIndex(Switch), - UndefValue::get(PN->getType())); + // loop structure and put the block on an dead code path. + + BasicBlock *SISucc = SI->getSuccessor(i); + BasicBlock* Old = SI->getParent(); + BasicBlock* Split = SplitBlock(Old, SI, this); + + Instruction* OldTerm = Old->getTerminator(); + BranchInst::Create(Split, SISucc, + ConstantInt::getTrue(Context), OldTerm); + + LPM->deleteSimpleAnalysisValue(Old->getTerminator(), L); + Old->getTerminator()->eraseFromParent(); + + PHINode *PN; + for (BasicBlock::iterator II = SISucc->begin(); + (PN = dyn_cast<PHINode>(II)); ++II) { + Value *InVal = PN->removeIncomingValue(Split, false); + PN->addIncoming(InVal, Old); + } + + SI->removeCase(i); break; } } |