[llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopUnroll.cpp
Owen Anderson
resistor at mac.com
Sun Aug 27 19:10:00 PDT 2006
Changes in directory llvm/lib/Transforms/Scalar:
LoopUnroll.cpp updated: 1.26 -> 1.27
---
Log message:
Make LoopUnroll fold excessive BasicBlocks. This results in a significant speedup of
gccas on 252.eon
---
Diffs of the changes: (+89 -9)
LoopUnroll.cpp | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 89 insertions(+), 9 deletions(-)
Index: llvm/lib/Transforms/Scalar/LoopUnroll.cpp
diff -u llvm/lib/Transforms/Scalar/LoopUnroll.cpp:1.26 llvm/lib/Transforms/Scalar/LoopUnroll.cpp:1.27
--- llvm/lib/Transforms/Scalar/LoopUnroll.cpp:1.26 Sun Aug 27 17:42:52 2006
+++ llvm/lib/Transforms/Scalar/LoopUnroll.cpp Sun Aug 27 21:09:46 2006
@@ -25,6 +25,7 @@
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Support/CFG.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
@@ -48,6 +49,7 @@
public:
virtual bool runOnFunction(Function &F);
bool visitLoop(Loop *L);
+ BasicBlock* FoldBlockIntoPredecessor(BasicBlock* BB);
/// This transformation requires natural loop information & requires that
/// loop preheaders be inserted into the CFG...
@@ -118,6 +120,76 @@
}
}
+// FoldBlockIntoPredecessor - Folds a basic block into its predecessor if it
+// only has one predecessor, and that predecessor only has one successor.
+// Returns the new combined block.
+BasicBlock* LoopUnroll::FoldBlockIntoPredecessor(BasicBlock* BB) {
+ // Merge basic blocks into their predecessor if there is only one distinct
+ // pred, and if there is only one distinct successor of the predecessor, and
+ // if there are no PHI nodes.
+ //
+ pred_iterator PI(pred_begin(BB)), PE(pred_end(BB));
+ BasicBlock *OnlyPred = *PI++;
+ for (; PI != PE; ++PI) // Search all predecessors, see if they are all same
+ if (*PI != OnlyPred) {
+ OnlyPred = 0; // There are multiple different predecessors...
+ break;
+ }
+
+ BasicBlock *OnlySucc = 0;
+ if (OnlyPred && OnlyPred != BB && // Don't break self loops
+ OnlyPred->getTerminator()->getOpcode() != Instruction::Invoke) {
+ // Check to see if there is only one distinct successor...
+ succ_iterator SI(succ_begin(OnlyPred)), SE(succ_end(OnlyPred));
+ OnlySucc = BB;
+ for (; SI != SE; ++SI)
+ if (*SI != OnlySucc) {
+ OnlySucc = 0; // There are multiple distinct successors!
+ break;
+ }
+ }
+
+ if (OnlySucc) {
+ DEBUG(std::cerr << "Merging: " << *BB << "into: " << *OnlyPred);
+ TerminatorInst *Term = OnlyPred->getTerminator();
+
+ // Resolve any PHI nodes at the start of the block. They are all
+ // guaranteed to have exactly one entry if they exist, unless there are
+ // multiple duplicate (but guaranteed to be equal) entries for the
+ // incoming edges. This occurs when there are multiple edges from
+ // OnlyPred to OnlySucc.
+ //
+ while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) {
+ PN->replaceAllUsesWith(PN->getIncomingValue(0));
+ BB->getInstList().pop_front(); // Delete the phi node...
+ }
+
+ // Delete the unconditional branch from the predecessor...
+ OnlyPred->getInstList().pop_back();
+
+ // Move all definitions in the successor to the predecessor...
+ OnlyPred->getInstList().splice(OnlyPred->end(), BB->getInstList());
+
+ // Make all PHI nodes that referred to BB now refer to Pred as their
+ // source...
+ BB->replaceAllUsesWith(OnlyPred);
+
+ std::string OldName = BB->getName();
+
+ // Erase basic block from the function...
+ LI->removeBlock(BB);
+ BB->eraseFromParent();
+
+ // Inherit predecessors name if it exists...
+ if (!OldName.empty() && !OnlyPred->hasName())
+ OnlyPred->setName(OldName);
+
+ return OnlyPred;
+ }
+
+ return 0;
+}
+
bool LoopUnroll::visitLoop(Loop *L) {
bool Changed = false;
@@ -247,13 +319,7 @@
RemapInstruction(I, LastValueMap);
}
- // Insert the branches that link the different iterations together
- for (unsigned i = 0; i < Latches.size()-1; ++i)
- new BranchInst(Headers[i+1], Latches[i]);
- // Finally, add an unconditional branch to the block to continue into the exit
- // block.
- new BranchInst(LoopExit, Latches[Latches.size()-1]);
// Update PHI nodes that reference the final latch block
if (TripCount > 1) {
@@ -281,14 +347,28 @@
PHINode *PN = OrigPHINode[i];
PN->replaceAllUsesWith(PN->getIncomingValueForBlock(Preheader));
Header->getInstList().erase(PN);
- }
-
+ }
+
+ // Insert the branches that link the different iterations together
+ for (unsigned i = 0; i < Latches.size()-1; ++i) {
+ new BranchInst(Headers[i+1], Latches[i]);
+ if(BasicBlock* Fold = FoldBlockIntoPredecessor(Headers[i+1])) {
+ std::replace(Latches.begin(), Latches.end(), Headers[i+1], Fold);
+ std::replace(Headers.begin(), Headers.end(), Headers[i+1], Fold);
+ }
+ }
+
+ // Finally, add an unconditional branch to the block to continue into the exit
+ // block.
+ new BranchInst(LoopExit, Latches[Latches.size()-1]);
+ FoldBlockIntoPredecessor(LoopExit);
+
// At this point, the code is well formed. We now do a quick sweep over the
// inserted code, doing constant propagation and dead code elimination as we
// go.
const std::vector<BasicBlock*> &NewLoopBlocks = L->getBlocks();
for (std::vector<BasicBlock*>::const_iterator BB = NewLoopBlocks.begin(),
- E = NewLoopBlocks.end(); BB != E; ++BB)
+ BBE = NewLoopBlocks.end(); BB != BBE; ++BB)
for (BasicBlock::iterator I = (*BB)->begin(), E = (*BB)->end(); I != E; ) {
Instruction *Inst = I++;
More information about the llvm-commits
mailing list