aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/LoopUnroll.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Scalar/LoopUnroll.cpp')
-rw-r--r--lib/Transforms/Scalar/LoopUnroll.cpp45
1 files changed, 43 insertions, 2 deletions
diff --git a/lib/Transforms/Scalar/LoopUnroll.cpp b/lib/Transforms/Scalar/LoopUnroll.cpp
index 8b296cb768..02cc509cc2 100644
--- a/lib/Transforms/Scalar/LoopUnroll.cpp
+++ b/lib/Transforms/Scalar/LoopUnroll.cpp
@@ -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;