[llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopUnroll.cpp

Chris Lattner lattner at cs.uiuc.edu
Sun Apr 18 01:28:01 PDT 2004


Changes in directory llvm/lib/Transforms/Scalar:

LoopUnroll.cpp updated: 1.2 -> 1.3

---
Log message:

After unrolling our single basic block loop, fold it into the preheader and exit 
block.  The primary motivation for doing this is that we can now unroll nested loops.

This makes a pretty big difference in some cases.  For example, in 183.equake,
we are now beating the native compiler with the CBE, and we are a lot closer 
with LLC.

I'm now going to play around a bit with the unroll factor and see what effect
it really has.


---
Diffs of the changes:  (+43 -2)

Index: llvm/lib/Transforms/Scalar/LoopUnroll.cpp
diff -u llvm/lib/Transforms/Scalar/LoopUnroll.cpp:1.2 llvm/lib/Transforms/Scalar/LoopUnroll.cpp:1.3
--- llvm/lib/Transforms/Scalar/LoopUnroll.cpp:1.2	Sun Apr 18 00:38:37 2004
+++ llvm/lib/Transforms/Scalar/LoopUnroll.cpp	Sun Apr 18 01:27:43 2004
@@ -27,6 +27,7 @@
 #include "Support/CommandLine.h"
 #include "Support/Debug.h"
 #include "Support/Statistic.h"
+#include "Support/STLExtras.h"
 #include <cstdio>
 using namespace llvm;
 
@@ -34,7 +35,7 @@
   Statistic<> NumUnrolled("loop-unroll", "Number of loops completely unrolled");
 
   cl::opt<unsigned>
-  UnrollThreshold("unroll-threshold", cl::init(100), cl::Hidden,
+  UnrollThreshold("unroll-threshold", cl::init(250), cl::Hidden,
                   cl::desc("The cut-off point for loop unrolling"));
 
   class LoopUnroll : public FunctionPass {
@@ -108,6 +109,17 @@
   }
 }
 
+static void ChangeExitBlocksFromTo(Loop::iterator I, Loop::iterator E,
+                                   BasicBlock *Old, BasicBlock *New) {
+  for (; I != E; ++I) {
+    Loop *L = *I;
+    if (L->hasExitBlock(Old)) {
+      L->changeExitBlock(Old, New);
+      ChangeExitBlocksFromTo(L->begin(), L->end(), Old, New);
+    }
+  }
+}
+
 
 bool LoopUnroll::visitLoop(Loop *L) {
   bool Changed = false;
@@ -256,7 +268,36 @@
 
   // FIXME: Should update dominator analyses
 
-  // FIXME: Should fold into preheader and exit block
+
+  // Now that everything is up-to-date that will be, we fold the loop block into
+  // the preheader and exit block, updating our analyses as we go.
+  LoopExit->getInstList().splice(LoopExit->begin(), BB->getInstList(),
+                                 BB->getInstList().begin(),
+                                 prior(BB->getInstList().end()));
+  LoopExit->getInstList().splice(LoopExit->begin(), Preheader->getInstList(),
+                                 Preheader->getInstList().begin(),
+                                 prior(Preheader->getInstList().end()));
+
+  // Make all other blocks in the program branch to LoopExit now instead of
+  // Preheader.
+  Preheader->replaceAllUsesWith(LoopExit);
+
+  // Remove BB and LoopExit from our analyses.
+  LI->removeBlock(Preheader);
+  LI->removeBlock(BB);
+
+  // If any loops used Preheader as an exit block, update them to use LoopExit.
+  if (Parent)
+    ChangeExitBlocksFromTo(Parent->begin(), Parent->end(),
+                           Preheader, LoopExit);
+  else
+    ChangeExitBlocksFromTo(LI->begin(), LI->end(),
+                           Preheader, LoopExit);
+
+
+  // Actually delete the blocks now.
+  LoopExit->getParent()->getBasicBlockList().erase(Preheader);
+  LoopExit->getParent()->getBasicBlockList().erase(BB);
 
   ++NumUnrolled;
   return true;





More information about the llvm-commits mailing list