Add facility that allows LoopPass to re-insert a loop into
Loop Pass Manager's queue.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34509 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h
index 046da6f..b3d4c6e 100644
--- a/include/llvm/Analysis/LoopPass.h
+++ b/include/llvm/Analysis/LoopPass.h
@@ -85,10 +85,15 @@
   // Delete loop from the loop queue. This is used by Loop pass to inform
   // Loop Pass Manager that it should skip rest of the passes for this loop.
   void deleteLoopFromQueue(Loop *L);
+
+  // Reoptimize this loop. LPPassManager will re-insert this loop into the
+  // queue. This allows LoopPass to change loop nest for the loop. This
+  // utility may send LPPassManager into infinite loops so use caution.
+  void redoLoop(Loop *L);
 private:
   LoopQueue *LQ;
   bool skipThisLoop;
-
+  bool redoThisLoop;
 };
 
 } // End llvm namespace
diff --git a/lib/Analysis/LoopPass.cpp b/lib/Analysis/LoopPass.cpp
index 22d542b..dc5c568 100644
--- a/lib/Analysis/LoopPass.cpp
+++ b/lib/Analysis/LoopPass.cpp
@@ -50,6 +50,8 @@
 /// LPPassManager manages FPPassManagers and CalLGraphSCCPasses.
 
 LPPassManager::LPPassManager(int Depth) : PMDataManager(Depth) { 
+  skipThisLoop = false;
+  redoThisLoop = false;
   LQ = new LoopQueue(); 
 }
 
@@ -64,6 +66,13 @@
   skipThisLoop = true;
 }
 
+// Reoptimize this loop. LPPassManager will re-insert this loop into the
+// queue. This allows LoopPass to change loop nest for the loop. This
+// utility may send LPPassManager into infinite loops so use caution.
+void LPPassManager::redoLoop(Loop *L) {
+  redoThisLoop = true;
+}
+
 // Recurse through all subloops and all loops  into LQ.
 static void addLoopIntoQueue(Loop *L, LoopQueue *LQ) {
   for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I)
@@ -89,6 +98,7 @@
       
     Loop *L  = LQ->top();
     skipThisLoop = false;
+    redoThisLoop = false;
 
     // Run all passes on current SCC
     for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {  
@@ -124,6 +134,9 @@
     
     // Pop the loop from queue after running all passes.
     LQ->pop();
+    
+    if (redoThisLoop)
+      LQ->push(L);
   }
 
   return Changed;