From c12d9b9dfbba233c847f74facf3c0deafae4523f Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Thu, 11 Aug 2011 20:27:32 +0000 Subject: [PATCH] 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 --- lib/Analysis/LoopInfo.cpp | 45 +++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp index 7bbe506fe1e..af35462544e 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();