aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils/LoopSimplify.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-05-12 22:04:34 +0000
committerChris Lattner <sabre@nondot.org>2003-05-12 22:04:34 +0000
commit8f6396e80fa60e4ff79ddf7d81381d726405ac45 (patch)
tree172584a46e956cacc697f0d845f09a76f0bf97c5 /lib/Transforms/Utils/LoopSimplify.cpp
parent0673d475c0b51dcd4d34705c5f700eb3f7c7b13f (diff)
Fix bug: LoopPreheaders/2003-05-12-PreheaderExitOfChild.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6153 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/LoopSimplify.cpp')
-rw-r--r--lib/Transforms/Utils/LoopSimplify.cpp24
1 files changed, 19 insertions, 5 deletions
diff --git a/lib/Transforms/Utils/LoopSimplify.cpp b/lib/Transforms/Utils/LoopSimplify.cpp
index d5988b1652..7576b01130 100644
--- a/lib/Transforms/Utils/LoopSimplify.cpp
+++ b/lib/Transforms/Utils/LoopSimplify.cpp
@@ -167,6 +167,19 @@ BasicBlock *Preheaders::SplitBlockPredecessors(BasicBlock *BB,
return NewBB;
}
+// ChangeExitBlock - This recursive function is used to change any exit blocks
+// that use OldExit to use NewExit instead. This is recursive because children
+// may need to be processed as well.
+//
+static void ChangeExitBlock(Loop *L, BasicBlock *OldExit, BasicBlock *NewExit) {
+ if (L->hasExitBlock(OldExit)) {
+ L->changeExitBlock(OldExit, NewExit);
+ const std::vector<Loop*> &SubLoops = L->getSubLoops();
+ for (unsigned i = 0, e = SubLoops.size(); i != e; ++i)
+ ChangeExitBlock(SubLoops[i], OldExit, NewExit);
+ }
+}
+
/// InsertPreheaderForLoop - Once we discover that a loop doesn't have a
/// preheader, this method is called to insert one. This method has two phases:
@@ -197,18 +210,19 @@ void Preheaders::InsertPreheaderForLoop(Loop *L) {
// If the header for the loop used to be an exit node for another loop, then
// we need to update this to know that the loop-preheader is now the exit
// node. Note that the only loop that could have our header as an exit node
- // is a sibling loop, ie, one with the same parent loop.
+ // is a sibling loop, ie, one with the same parent loop, or one if it's
+ // children.
+ //
const std::vector<Loop*> *ParentSubLoops;
if (Loop *Parent = L->getParentLoop())
ParentSubLoops = &Parent->getSubLoops();
else // Must check top-level loops...
ParentSubLoops = &getAnalysis<LoopInfo>().getTopLevelLoops();
- // Loop over all sibling loops, performing the substitution...
+ // Loop over all sibling loops, performing the substitution (recursively to
+ // include child loops)...
for (unsigned i = 0, e = ParentSubLoops->size(); i != e; ++i)
- if ((*ParentSubLoops)[i]->hasExitBlock(Header))
- (*ParentSubLoops)[i]->changeExitBlock(Header, NewBB);
-
+ ChangeExitBlock((*ParentSubLoops)[i], Header, NewBB);
DominatorSet &DS = getAnalysis<DominatorSet>(); // Update dominator info
{