[llvm] r257191 - LoopInfo: Simplify ownership of Loop objects

Justin Bogner via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 8 11:08:53 PST 2016


Author: bogner
Date: Fri Jan  8 13:08:53 2016
New Revision: 257191

URL: http://llvm.org/viewvc/llvm-project?rev=257191&view=rev
Log:
LoopInfo: Simplify ownership of Loop objects

It's strange that LoopInfo mostly owns the Loop objects, but that it
defers deleting them to the loop pass manager. Instead, change the
oddly named "updateUnloop" to "markAsRemoved" and have it queue the
Loop object for deletion. We can't delete the Loop immediately when we
remove it, since we need its pointer identity still, so we'll mark the
object as "invalid" so that clients can see what's going on.

Modified:
    llvm/trunk/include/llvm/Analysis/LoopInfo.h
    llvm/trunk/lib/Analysis/LoopInfo.cpp
    llvm/trunk/lib/Analysis/LoopPass.cpp
    llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp
    llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp
    llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp
    llvm/trunk/test/Transforms/LoopUnroll/unloop.ll

Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=257191&r1=257190&r2=257191&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Fri Jan  8 13:08:53 2016
@@ -73,9 +73,8 @@ class LoopBase {
 
   SmallPtrSet<const BlockT*, 8> DenseBlockSet;
 
-  /// Indicator that this loops has been "unlooped", so there's no loop here
-  /// anymore.
-  bool IsUnloop = false;
+  /// Indicator that this loop is no longer a valid loop.
+  bool IsInvalid = false;
 
   LoopBase(const LoopBase<BlockT, LoopT> &) = delete;
   const LoopBase<BlockT, LoopT>&
@@ -154,12 +153,11 @@ public:
     return Blocks.size();
   }
 
-  /// Mark this loop as having been unlooped - the last backedge was removed and
-  /// we no longer have a loop.
-  void markUnlooped() { IsUnloop = true; }
+  /// Invalidate the loop, indicating that it is no longer a loop.
+  void invalidate() { IsInvalid = true; }
 
-  /// Return true if this no longer represents a loop.
-  bool isUnloop() const { return IsUnloop; }
+  /// Return true if this loop is no longer valid.
+  bool isInvalid() { return IsInvalid; }
 
   /// isLoopExiting - True if terminator in the block can branch to another
   /// block that is outside of the current loop.
@@ -507,6 +505,8 @@ class LoopInfoBase {
   // BBMap - Mapping of basic blocks to the inner most loop they occur in
   DenseMap<const BlockT *, LoopT *> BBMap;
   std::vector<LoopT *> TopLevelLoops;
+  std::vector<LoopT *> RemovedLoops;
+
   friend class LoopBase<BlockT, LoopT>;
   friend class LoopInfo;
 
@@ -538,6 +538,9 @@ public:
     for (auto *L : TopLevelLoops)
       delete L;
     TopLevelLoops.clear();
+    for (auto *L : RemovedLoops)
+      delete L;
+    RemovedLoops.clear();
   }
 
   /// iterator/begin/end - The interface to the top-level loops in the current
@@ -670,12 +673,11 @@ public:
 
   // Most of the public interface is provided via LoopInfoBase.
 
-  /// updateUnloop - Update LoopInfo after removing the last backedge from a
-  /// loop--now the "unloop". This updates the loop forest and parent loops for
-  /// each block so that Unloop is no longer referenced, but does not actually
-  /// delete the Unloop object. Generally, the loop pass manager should manage
-  /// deleting the Unloop.
-  void updateUnloop(Loop *Unloop);
+  /// Update LoopInfo after removing the last backedge from a loop. This updates
+  /// the loop forest and parent loops for each block so that \c L is no longer
+  /// referenced, but does not actually delete \c L immediately. The pointer
+  /// will remain valid until this LoopInfo's memory is released.
+  void markAsRemoved(Loop *L);
 
   /// replacementPreservesLCSSAForm - Returns true if replacing From with To
   /// everywhere is guaranteed to preserve LCSSA form.

Modified: llvm/trunk/lib/Analysis/LoopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopInfo.cpp?rev=257191&r1=257190&r2=257191&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/LoopInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/LoopInfo.cpp Fri Jan  8 13:08:53 2016
@@ -637,8 +637,10 @@ LoopInfo::LoopInfo(const DominatorTreeBa
   analyze(DomTree);
 }
 
-void LoopInfo::updateUnloop(Loop *Unloop) {
-  Unloop->markUnlooped();
+void LoopInfo::markAsRemoved(Loop *Unloop) {
+  assert(!Unloop->isInvalid() && "Loop has already been removed");
+  Unloop->invalidate();
+  RemovedLoops.push_back(Unloop);
 
   // First handle the special case of no parent loop to simplify the algorithm.
   if (!Unloop->getParentLoop()) {

Modified: llvm/trunk/lib/Analysis/LoopPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopPass.cpp?rev=257191&r1=257190&r2=257191&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/LoopPass.cpp (original)
+++ llvm/trunk/lib/Analysis/LoopPass.cpp Fri Jan  8 13:08:53 2016
@@ -178,8 +178,9 @@ bool LPPassManager::runOnFunction(Functi
 
   // Walk Loops
   while (!LQ.empty()) {
-
+    bool LoopWasDeleted = false;
     CurrentLoop = LQ.back();
+
     // Run all passes on the current Loop.
     for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
       LoopPass *P = getContainedPass(Index);
@@ -196,15 +197,15 @@ bool LPPassManager::runOnFunction(Functi
 
         Changed |= P->runOnLoop(CurrentLoop, *this);
       }
+      LoopWasDeleted = CurrentLoop->isInvalid();
 
       if (Changed)
         dumpPassInfo(P, MODIFICATION_MSG, ON_LOOP_MSG,
-                     CurrentLoop->isUnloop()
-                         ? "<deleted>"
-                         : CurrentLoop->getHeader()->getName());
+                     LoopWasDeleted ? "<deleted>"
+                                    : CurrentLoop->getHeader()->getName());
       dumpPreservedSet(P);
 
-      if (CurrentLoop->isUnloop()) {
+      if (LoopWasDeleted) {
         // Notify passes that the loop is being deleted.
         deleteSimpleAnalysisLoop(CurrentLoop);
       } else {
@@ -226,12 +227,11 @@ bool LPPassManager::runOnFunction(Functi
 
       removeNotPreservedAnalysis(P);
       recordAvailableAnalysis(P);
-      removeDeadPasses(P, CurrentLoop->isUnloop()
-                              ? "<deleted>"
-                              : CurrentLoop->getHeader()->getName(),
+      removeDeadPasses(P, LoopWasDeleted ? "<deleted>"
+                                         : CurrentLoop->getHeader()->getName(),
                        ON_LOOP_MSG);
 
-      if (CurrentLoop->isUnloop())
+      if (LoopWasDeleted)
         // Do not run other passes on this loop.
         break;
     }
@@ -239,12 +239,11 @@ bool LPPassManager::runOnFunction(Functi
     // If the loop was deleted, release all the loop passes. This frees up
     // some memory, and avoids trouble with the pass manager trying to call
     // verifyAnalysis on them.
-    if (CurrentLoop->isUnloop()) {
+    if (LoopWasDeleted) {
       for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
         Pass *P = getContainedPass(Index);
         freePass(P, "<deleted>", ON_LOOP_MSG);
       }
-      delete CurrentLoop;
     }
 
     // Pop the loop from queue after running all passes.

Modified: llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp?rev=257191&r1=257190&r2=257191&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp Fri Jan  8 13:08:53 2016
@@ -38,7 +38,7 @@ namespace {
     static char ID; // Pass identification, replacement for typeid
     unsigned NumLoops;
 
-    explicit LoopExtractor(unsigned numLoops = ~0) 
+    explicit LoopExtractor(unsigned numLoops = ~0)
       : LoopPass(ID), NumLoops(numLoops) {
         initializeLoopExtractorPass(*PassRegistry::getPassRegistry());
       }
@@ -143,7 +143,7 @@ bool LoopExtractor::runOnLoop(Loop *L, L
       Changed = true;
       // After extraction, the loop is replaced by a function call, so
       // we shouldn't try to run any more loop passes on it.
-      LI.updateUnloop(L);
+      LI.markAsRemoved(L);
     }
     ++NumExtracted;
   }

Modified: llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp?rev=257191&r1=257190&r2=257191&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Fri Jan  8 13:08:53 2016
@@ -245,7 +245,7 @@ bool LoopDeletion::runOnLoop(Loop *L, LP
     loopInfo.removeBlock(BB);
 
   // The last step is to update LoopInfo now that we've eliminated this loop.
-  loopInfo.updateUnloop(L);
+  loopInfo.markAsRemoved(L);
   Changed = true;
 
   ++NumDeleted;

Modified: llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp?rev=257191&r1=257190&r2=257191&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Fri Jan  8 13:08:53 2016
@@ -528,7 +528,7 @@ bool llvm::UnrollLoop(Loop *L, unsigned
   Loop *OuterL = L->getParentLoop();
   // Update LoopInfo if the loop is completely removed.
   if (CompletelyUnroll)
-    LI->updateUnloop(L);;
+    LI->markAsRemoved(L);
 
   // If we have a pass and a DominatorTree we should re-simplify impacted loops
   // to ensure subsequent analyses can rely on this form. We want to simplify
@@ -542,7 +542,7 @@ bool llvm::UnrollLoop(Loop *L, unsigned
 
       // LCSSA must be performed on the outermost affected loop. The unrolled
       // loop's last loop latch is guaranteed to be in the outermost loop after
-      // LoopInfo's been updated by updateUnloop.
+      // LoopInfo's been updated by markAsRemoved.
       Loop *LatchLoop = LI->getLoopFor(Latches.back());
       if (!OuterL->contains(LatchLoop))
         while (OuterL->getParentLoop() != LatchLoop)

Modified: llvm/trunk/test/Transforms/LoopUnroll/unloop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnroll/unloop.ll?rev=257191&r1=257190&r2=257191&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopUnroll/unloop.ll (original)
+++ llvm/trunk/test/Transforms/LoopUnroll/unloop.ll Fri Jan  8 13:08:53 2016
@@ -1,6 +1,6 @@
 ; RUN: opt < %s -S -loop-unroll -verify-loop-info | FileCheck %s
 ;
-; Unit tests for LoopInfo::updateUnloop.
+; Unit tests for LoopInfo::markAsRemoved.
 
 declare i1 @check() nounwind
 




More information about the llvm-commits mailing list