After unrolling our single basic block loop, fold it into the preheader and exit
authorChris Lattner <sabre@nondot.org>
Sun, 18 Apr 2004 06:27:43 +0000 (06:27 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 18 Apr 2004 06:27:43 +0000 (06:27 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13034 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/LoopUnroll.cpp

index 8b296cb7685c186ca749adf8b0c7ba2ba65ceda2..02cc509cc2f42aac5e9f95c9f1a0142392c75270 100644 (file)
@@ -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 @@ namespace {
   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 inline void RemapInstruction(Instruction *I,
   }
 }
 
+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 @@ bool LoopUnroll::visitLoop(Loop *L) {
 
   // 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;