diff options
author | Andrew Trick <atrick@apple.com> | 2011-08-11 20:27:32 +0000 |
---|---|---|
committer | Andrew Trick <atrick@apple.com> | 2011-08-11 20:27:32 +0000 |
commit | c12c30a67065f351acd18b08a429b6c3b8a3f66c (patch) | |
tree | 96e0f8271fba7303de9cd7e488e66f67342cb6f3 /llvm/lib/Analysis/LoopInfo.cpp | |
parent | 60663403018ac7da2415e4ff046c984ee32f931b (diff) | |
download | bcm5719-llvm-c12c30a67065f351acd18b08a429b6c3b8a3f66c.tar.gz bcm5719-llvm-c12c30a67065f351acd18b08a429b6c3b8a3f66c.zip |
Fix for LoopInfo::updateUnloop. Remove subloop blocks from former
ancestor loops.
I have a unit test that depends on scev-unroll, which unfortunately
isn't checked in. But I will check it in when I can.
llvm-svn: 137341
Diffstat (limited to 'llvm/lib/Analysis/LoopInfo.cpp')
-rw-r--r-- | llvm/lib/Analysis/LoopInfo.cpp | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp index 7bbe506fe1e..af35462544e 100644 --- a/llvm/lib/Analysis/LoopInfo.cpp +++ b/llvm/lib/Analysis/LoopInfo.cpp @@ -411,6 +411,8 @@ public: void updateBlockParents(); + void removeBlocksFromAncestors(); + void updateSubloopParents(); protected: @@ -467,6 +469,31 @@ void UnloopUpdater::updateBlockParents() { } } +/// removeBlocksFromAncestors - Remove unloop's blocks from all ancestors below +/// their new parents. +void UnloopUpdater::removeBlocksFromAncestors() { + // Remove unloop's blocks from all ancestors below their new parents. + for (Loop::block_iterator BI = Unloop->block_begin(), + BE = Unloop->block_end(); BI != BE; ++BI) { + Loop *NewParent = LI->getLoopFor(*BI); + // If this block is an immediate subloop, remove all blocks (including + // nested subloops) from ancestors below the new parent loop. + // Otherwise, if this block is in a nested subloop, skip it. + if (SubloopParents.count(NewParent)) + NewParent = SubloopParents[NewParent]; + else if (Unloop->contains(NewParent)) + continue; + + // Remove blocks from former Ancestors except Unloop itself which will be + // deleted. + for (Loop *OldParent = Unloop->getParentLoop(); OldParent != NewParent; + OldParent = OldParent->getParentLoop()) { + assert(OldParent && "new loop is not an ancestor of the original"); + OldParent->removeBlockFromLoop(*BI); + } + } +} + /// updateSubloopParents - Update the parent loop for all subloops directly /// nested within unloop. void UnloopUpdater::updateSubloopParents() { @@ -605,22 +632,8 @@ void LoopInfo::updateUnloop(Loop *Unloop) { UnloopUpdater Updater(Unloop, this); Updater.updateBlockParents(); - // Remove unloop's blocks from all ancestors below their new parents. - for (Loop::block_iterator BI = Unloop->block_begin(), - BE = Unloop->block_end(); BI != BE; ++BI) { - Loop *NewParent = getLoopFor(*BI); - // If this block is in a subloop, skip it. - if (Unloop->contains(NewParent)) - continue; - - // Remove blocks from former Ancestors except Unloop itself which will be - // deleted. - for (Loop *OldParent = Unloop->getParentLoop(); OldParent != NewParent; - OldParent = OldParent->getParentLoop()) { - assert(OldParent && "new loop is not an ancestor of the original"); - OldParent->removeBlockFromLoop(*BI); - } - } + // Remove blocks from former ancestor loops. + Updater.removeBlocksFromAncestors(); // Add direct subloops as children in their new parent loop. Updater.updateSubloopParents(); |