diff options
author | Chris Lattner <sabre@nondot.org> | 2006-02-10 23:26:14 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-02-10 23:26:14 +0000 |
commit | e825593bf2f8ab00878ea8086e982bf689063c79 (patch) | |
tree | 8dab547fa4f6a0ce5ebbd10503563ba947f126a2 /lib/Transforms/Scalar/LoopUnswitch.cpp | |
parent | b2bc315eac9e3211aafb484479685d1a9bdee5a9 (diff) |
Update PHI nodes in successors of exit blocks.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26113 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/LoopUnswitch.cpp')
-rw-r--r-- | lib/Transforms/Scalar/LoopUnswitch.cpp | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp index ac64a9e551..15e1d992f8 100644 --- a/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -256,6 +256,16 @@ bool LoopUnswitch::visitLoop(Loop *L) { // loop. for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); I != E; ++I) { + for (BasicBlock::iterator BBI = (*I)->begin(), E = (*I)->end(); + BBI != E; ++BBI) + if (SelectInst *SI = dyn_cast<SelectInst>(BBI)) { + Value *LoopCond = FindLIVLoopCondition(SI->getCondition(), L, Changed); + if (LoopCond == 0) continue; + + //if (UnswitchIfProfitable(LoopCond, + std::cerr << "LOOP INVARIANT SELECT: " << *SI; + } + TerminatorInst *TI = (*I)->getTerminator(); // FIXME: Handle invariant select instructions. @@ -523,13 +533,32 @@ void LoopUnswitch::VersionLoop(Value *LIC, Loop *L, Loop *&Out1, Loop *&Out2) { // Now we create the new Loop object for the versioned loop. Loop *NewLoop = CloneLoop(L, L->getParentLoop(), ValueMap, LI); - if (Loop *Parent = L->getParentLoop()) { + Loop *ParentLoop = L->getParentLoop(); + if (ParentLoop) { // Make sure to add the cloned preheader and exit blocks to the parent loop // as well. - Parent->addBasicBlockToLoop(NewBlocks[0], *LI); - for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) - Parent->addBasicBlockToLoop(cast<BasicBlock>(ValueMap[ExitBlocks[i]]), - *LI); + ParentLoop->addBasicBlockToLoop(NewBlocks[0], *LI); + } + + for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) { + BasicBlock *NewExit = cast<BasicBlock>(ValueMap[ExitBlocks[i]]); + if (ParentLoop) + ParentLoop->addBasicBlockToLoop(cast<BasicBlock>(NewExit), *LI); + + assert(NewExit->getTerminator()->getNumSuccessors() == 1 && + "Exit block should have been split to have one successor!"); + BasicBlock *ExitSucc = NewExit->getTerminator()->getSuccessor(0); + + // If the successor of the exit block had PHI nodes, add an entry for + // NewExit. + PHINode *PN; + for (BasicBlock::iterator I = ExitSucc->begin(); + (PN = dyn_cast<PHINode>(I)); ++I) { + Value *V = PN->getIncomingValueForBlock(ExitBlocks[i]); + std::map<const Value *, Value*>::iterator It = ValueMap.find(V); + if (It != ValueMap.end()) V = It->second; + PN->addIncoming(V, NewExit); + } } // Rewrite the code to refer to itself. |