[llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
Owen Anderson
resistor at mac.com
Mon Jun 26 00:44:50 PDT 2006
Changes in directory llvm/lib/Transforms/Scalar:
LoopUnswitch.cpp updated: 1.40 -> 1.41
---
Log message:
Make LoopUnswitch able to unswitch loops with live-out values by taking advantage
of LCSSA. This results several times the number of unswitchings occurring on
tests such and timberwolfmc, unix-tbl, and ldecod.
---
Diffs of the changes: (+63 -53)
LoopUnswitch.cpp | 116 +++++++++++++++++++++++++++++--------------------------
1 files changed, 63 insertions(+), 53 deletions(-)
Index: llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
diff -u llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.40 llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.41
--- llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.40 Tue Jun 13 23:46:17 2006
+++ llvm/lib/Transforms/Scalar/LoopUnswitch.cpp Mon Jun 26 02:44:36 2006
@@ -208,31 +208,6 @@
return Changed;
}
-
-/// LoopValuesUsedOutsideLoop - Return true if there are any values defined in
-/// the loop that are used by instructions outside of it.
-static bool LoopValuesUsedOutsideLoop(Loop *L) {
- // We will be doing lots of "loop contains block" queries. Loop::contains is
- // linear time, use a set to speed this up.
- std::set<BasicBlock*> LoopBlocks;
-
- for (Loop::block_iterator BB = L->block_begin(), E = L->block_end();
- BB != E; ++BB)
- LoopBlocks.insert(*BB);
-
- for (Loop::block_iterator BB = L->block_begin(), E = L->block_end();
- BB != E; ++BB) {
- for (BasicBlock::iterator I = (*BB)->begin(), E = (*BB)->end(); I != E; ++I)
- for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E;
- ++UI) {
- BasicBlock *UserBB = cast<Instruction>(*UI)->getParent();
- if (!LoopBlocks.count(UserBB))
- return true;
- }
- }
- return false;
-}
-
/// isTrivialLoopExitBlock - Check to see if all paths from BB either:
/// 1. Exit the loop with no side effects.
/// 2. Branch to the latch block with no side-effects.
@@ -391,17 +366,7 @@
<< L->getBlocks().size() << "\n");
return false;
}
-
- // If this loop has live-out values, we can't unswitch it. We need something
- // like loop-closed SSA form in order to know how to insert PHI nodes for
- // these values.
- if (LoopValuesUsedOutsideLoop(L)) {
- DEBUG(std::cerr << "NOT unswitching loop %" << L->getHeader()->getName()
- << ", a loop value is used outside loop! Cost: "
- << Cost << "\n");
- return false;
- }
-
+
// If this is a trivial condition to unswitch (which results in no code
// duplication), do it now.
Constant *CondVal;
@@ -456,18 +421,6 @@
// If the successor only has a single pred, split the top of the successor
// block.
assert(SP == BB && "CFG broken");
-
- // If this block has a single predecessor, remove any phi nodes. Unswitch
- // expect that, after split the edges from inside the loop to the exit
- // block, that there will be no phi nodes in the new exit block. Single
- // entry phi nodes break this assumption.
- BasicBlock::iterator I = Succ->begin();
- while (PHINode *PN = dyn_cast<PHINode>(I)) {
- PN->replaceAllUsesWith(PN->getIncomingValue(0));
- PN->eraseFromParent();
- I = Succ->begin();
- }
-
return SplitBlock(Succ, Succ->begin());
} else {
// Otherwise, if BB has a single successor, split it at the bottom of the
@@ -616,8 +569,8 @@
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.
+ // Split all of the edges from inside the loop to their exit blocks. Update
+ // the appropriate Phi nodes as we do so.
unsigned NumBlocks = L->getBlocks().size();
for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
@@ -627,8 +580,42 @@
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);
- }
+ BasicBlock* MiddleBlock = SplitEdge(Preds[j], ExitBlock);
+ BasicBlock* StartBlock = Preds[j];
+ BasicBlock* EndBlock;
+ if (MiddleBlock->getSinglePredecessor() == ExitBlock) {
+ EndBlock = MiddleBlock;
+ MiddleBlock = EndBlock->getSinglePredecessor();;
+ } else {
+ EndBlock = ExitBlock;
+ }
+
+ std::set<PHINode*> InsertedPHIs;
+ PHINode* OldLCSSA = 0;
+ for (BasicBlock::iterator I = EndBlock->begin();
+ (OldLCSSA = dyn_cast<PHINode>(I)); ++I) {
+ Value* OldValue = OldLCSSA->getIncomingValueForBlock(MiddleBlock);
+ PHINode* NewLCSSA = new PHINode(OldLCSSA->getType(),
+ OldLCSSA->getName() + ".us-lcssa",
+ MiddleBlock->getTerminator());
+ NewLCSSA->addIncoming(OldValue, StartBlock);
+ OldLCSSA->setIncomingValue(OldLCSSA->getBasicBlockIndex(MiddleBlock),
+ NewLCSSA);
+ InsertedPHIs.insert(NewLCSSA);
+ }
+
+ Instruction* InsertPt = EndBlock->begin();
+ while (dyn_cast<PHINode>(InsertPt)) ++InsertPt;
+ for (BasicBlock::iterator I = MiddleBlock->begin();
+ (OldLCSSA = dyn_cast<PHINode>(I)) && InsertedPHIs.count(OldLCSSA) == 0;
+ ++I) {
+ PHINode *NewLCSSA = new PHINode(OldLCSSA->getType(),
+ OldLCSSA->getName() + ".us-lcssa",
+ InsertPt);
+ OldLCSSA->replaceAllUsesWith(NewLCSSA);
+ NewLCSSA->addIncoming(OldLCSSA, MiddleBlock);
+ }
+ }
}
// The exit blocks may have been changed due to edge splitting, recompute.
@@ -967,7 +954,30 @@
// Found a dead case value. Don't remove PHI nodes in the
// successor if they become single-entry, those PHI nodes may
// be in the Users list.
- SI->getSuccessor(i)->removePredecessor(SI->getParent(), true);
+
+ // FIXME: This is a hack. We need to keep the successor around
+ // and hooked up so as to preserve the loop structure, because
+ // trying to update it is complicated. So instead we preserve the
+ // loop structure and put the block on an dead code path.
+
+ BasicBlock* Old = SI->getParent();
+ BasicBlock* Split = SplitBlock(Old, SI);
+
+ Instruction* OldTerm = Old->getTerminator();
+ BranchInst* Branch = new BranchInst(Split,
+ SI->getSuccessor(i),
+ ConstantBool::True,
+ OldTerm);
+
+ Old->getTerminator()->eraseFromParent();
+
+ for (BasicBlock::iterator II = SI->getSuccessor(i)->begin(),
+ IE = SI->getSuccessor(i)->end(); II != IE; ++II) {
+ if (isa<PHINode>(*II)) {
+ (*II).replaceUsesOfWith(Split, Old);
+ }
+ }
+
SI->removeCase(i);
break;
}
More information about the llvm-commits
mailing list