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 | c12d9b9dfbba233c847f74facf3c0deafae4523f (patch) | |
tree | 51b7ddda1259c6a647a6a77bd12059cb2a227c10 | |
parent | 26d2f0ac919f6ae868fe901fd4ad64af6f92da4d (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137341 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Analysis/LoopInfo.cpp | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp index 7bbe506fe1..af35462544 100644 --- a/lib/Analysis/LoopInfo.cpp +++ b/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(); |