mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-25 21:16:19 +00:00
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. llvm-svn: 13034
This commit is contained in:
parent
f2045a8c05
commit
33ec7f2f9f
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user