[llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Feb 10 15:16:51 PST 2006
Changes in directory llvm/lib/Transforms/Scalar:
LoopUnswitch.cpp updated: 1.14 -> 1.15
---
Log message:
Reform the unswitching code in terms of edge splitting, not block splitting.
---
Diffs of the changes: (+67 -49)
LoopUnswitch.cpp | 116 +++++++++++++++++++++++++++++++------------------------
1 files changed, 67 insertions(+), 49 deletions(-)
Index: llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
diff -u llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.14 llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.15
--- llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.14 Fri Feb 10 13:08:15 2006
+++ llvm/lib/Transforms/Scalar/LoopUnswitch.cpp Fri Feb 10 17:16:39 2006
@@ -68,7 +68,7 @@
private:
unsigned getLoopUnswitchCost(Loop *L, Value *LIC);
void VersionLoop(Value *LIC, Loop *L, Loop *&Out1, Loop *&Out2);
- BasicBlock *SplitBlock(BasicBlock *BB, bool SplitAtTop);
+ BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To);
void RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC, bool Val);
void UnswitchTrivialCondition(Loop *L, Value *Cond, bool EntersLoopOnCond,
BasicBlock *ExitBlock);
@@ -256,8 +256,6 @@
// loop.
for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
I != E; ++I) {
- for (BasicBlock::iterator BBI = (*I)->begin(), E = (*I)->end();
- BBI != E; ++BBI)
TerminatorInst *TI = (*I)->getTerminator();
// FIXME: Handle invariant select instructions.
@@ -329,31 +327,49 @@
return Changed;
}
-/// SplitBlock - Split the specified basic block into two pieces. If SplitAtTop
-/// is false, this splits the block so the second half only has an unconditional
-/// branch. If SplitAtTop is true, it makes it so the first half of the block
-/// only has an unconditional branch in it.
-///
-/// This method updates the LoopInfo for this function to correctly reflect the
-/// CFG changes made.
-///
-/// This routine returns the new basic block that was inserted, which is always
-/// the later part of the block.
-BasicBlock *LoopUnswitch::SplitBlock(BasicBlock *BB, bool SplitAtTop) {
+BasicBlock *LoopUnswitch::SplitEdge(BasicBlock *BB, BasicBlock *Succ) {
+ TerminatorInst *LatchTerm = BB->getTerminator();
+ unsigned SuccNum = 0;
+ for (unsigned i = 0, e = LatchTerm->getNumSuccessors(); ; ++i) {
+ assert(i != e && "Didn't find edge?");
+ if (LatchTerm->getSuccessor(i) == Succ) {
+ SuccNum = i;
+ break;
+ }
+ }
+
+ // If this is a critical edge, let SplitCriticalEdge do it.
+ if (SplitCriticalEdge(BB->getTerminator(), SuccNum, this))
+ return LatchTerm->getSuccessor(SuccNum);
+
+ // If the edge isn't critical, then BB has a single successor or Succ has a
+ // single pred. Split the block.
+ BasicBlock *BlockToSplit;
BasicBlock::iterator SplitPoint;
- if (!SplitAtTop)
+ if (BasicBlock *SP = Succ->getSinglePredecessor()) {
+ // If the successor only has a single pred, split the top of the successor
+ // block.
+ assert(SP == BB && "CFG broken");
+ BlockToSplit = Succ;
+ SplitPoint = Succ->begin();
+ } else {
+ // Otherwise, if BB has a single successor, split it at the bottom of the
+ // block.
+ assert(BB->getTerminator()->getNumSuccessors() == 1 &&
+ "Should have a single succ!");
+ BlockToSplit = BB;
SplitPoint = BB->getTerminator();
- else {
- SplitPoint = BB->begin();
- while (isa<PHINode>(SplitPoint)) ++SplitPoint;
}
-
- BasicBlock *New = BB->splitBasicBlock(SplitPoint, BB->getName()+".tail");
+
+ BasicBlock *New =
+ BlockToSplit->splitBasicBlock(SplitPoint,
+ BlockToSplit->getName()+".tail");
// New now lives in whichever loop that BB used to.
- if (Loop *L = LI->getLoopFor(BB))
+ if (Loop *L = LI->getLoopFor(BlockToSplit))
L->addBasicBlockToLoop(New, *LI);
return New;
}
+
// RemapInstruction - Convert the instruction operands from referencing the
@@ -406,40 +422,21 @@
<< " blocks] in Function " << L->getHeader()->getParent()->getName()
<< " on cond:" << *Cond << "\n");
- // First step, split the preahder, so that we know that there is a safe place
+ // First step, split the preheader, so that we know that there is a safe place
// to insert the conditional branch. We will change 'OrigPH' to have a
// conditional branch on Cond.
BasicBlock *OrigPH = L->getLoopPreheader();
- BasicBlock *NewPH = SplitBlock(OrigPH, false);
+ BasicBlock *NewPH = SplitEdge(OrigPH, L->getHeader());
// Now that we have a place to insert the conditional branch, create a place
// to branch to: this is the exit block out of the loop that we should
// short-circuit to.
- // Split this block now, so that the loop maintains its exit block.
+ // Split this edge now, so that the loop maintains its exit block.
assert(!L->contains(ExitBlock) && "Exit block is in the loop?");
- BasicBlock *NewExit;
- if (BasicBlock *SinglePred = ExitBlock->getSinglePredecessor()) {
- assert(SinglePred == L->getLoopLatch() && "Unexpected case");
- NewExit = SplitBlock(ExitBlock, true);
- } else {
- // Otherwise, this is a critical edge. Split block would split the wrong
- // edge here, so we use SplitCriticalEdge, which allows us to specify the
- // edge to split, not just the block.
- TerminatorInst *LatchTerm = L->getLoopLatch()->getTerminator();
- unsigned SuccNum = 0;
- for (unsigned i = 0, e = LatchTerm->getNumSuccessors(); ; ++i) {
- assert(i != e && "Didn't find edge?");
- if (LatchTerm->getSuccessor(i) == ExitBlock) {
- SuccNum = i;
- break;
- }
- }
- SplitCriticalEdge(LatchTerm, SuccNum, this);
- NewExit = LatchTerm->getSuccessor(SuccNum);
- assert(NewExit != ExitBlock && "Edge not split!");
- }
-
+ BasicBlock *NewExit = SplitEdge(L->getLoopLatch(), ExitBlock);
+ assert(NewExit != ExitBlock && "Edge not split!");
+
// Okay, now we have a position to branch from and a position to branch to,
// insert the new conditional branch.
new BranchInst(EnterOnCond ? NewPH : NewExit, EnterOnCond ? NewExit : NewPH,
@@ -467,12 +464,15 @@
<< " blocks] in Function " << F->getName()
<< " on cond:" << *LIC << "\n");
+ // LoopBlocks contains all of the basic blocks of the loop, including the
+ // preheader of the loop, the body of the loop, and the exit blocks of the
+ // loop, in that order.
std::vector<BasicBlock*> LoopBlocks;
// First step, split the preheader and exit blocks, and add these blocks to
// the LoopBlocks list.
BasicBlock *OrigPreheader = L->getLoopPreheader();
- LoopBlocks.push_back(SplitBlock(OrigPreheader, false));
+ LoopBlocks.push_back(SplitEdge(OrigPreheader, L->getHeader()));
// We want the loop to come after the preheader, but before the exit blocks.
LoopBlocks.insert(LoopBlocks.end(), L->block_begin(), L->block_end());
@@ -482,10 +482,28 @@
std::sort(ExitBlocks.begin(), ExitBlocks.end());
ExitBlocks.erase(std::unique(ExitBlocks.begin(), ExitBlocks.end()),
ExitBlocks.end());
+ // Split all of the edges from inside the loop to their exit blocks. This
+ // unswitching trivial: no phi nodes to update.
for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
- SplitBlock(ExitBlocks[i], true);
- LoopBlocks.push_back(ExitBlocks[i]);
+ BasicBlock *ExitBlock = ExitBlocks[i];
+ std::vector<BasicBlock*> Preds(pred_begin(ExitBlock), pred_end(ExitBlock));
+
+ for (unsigned j = 0, e = Preds.size(); j != e; ++j) {
+ assert(L->contains(Preds[j]) &&
+ "All preds of loop exit blocks must be the same loop!");
+ SplitEdge(Preds[j], ExitBlock);
+ }
}
+
+ // The exit blocks may have been changed due to edge splitting, recompute.
+ ExitBlocks.clear();
+ L->getExitBlocks(ExitBlocks);
+ std::sort(ExitBlocks.begin(), ExitBlocks.end());
+ ExitBlocks.erase(std::unique(ExitBlocks.begin(), ExitBlocks.end()),
+ ExitBlocks.end());
+
+ // Add exit blocks to the loop blocks.
+ LoopBlocks.insert(LoopBlocks.end(), ExitBlocks.begin(), ExitBlocks.end());
// Next step, clone all of the basic blocks that make up the loop (including
// the loop preheader and exit blocks), keeping track of the mapping between
More information about the llvm-commits
mailing list