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.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28912 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Owen Anderson 2006-06-26 07:44:36 +00:00
parent da08d2c39a
commit 2b67f07d2b

View File

@ -208,31 +208,6 @@ bool LoopUnswitch::visitLoop(Loop *L) {
return Changed; 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: /// isTrivialLoopExitBlock - Check to see if all paths from BB either:
/// 1. Exit the loop with no side effects. /// 1. Exit the loop with no side effects.
/// 2. Branch to the latch block with no side-effects. /// 2. Branch to the latch block with no side-effects.
@ -392,16 +367,6 @@ bool LoopUnswitch::UnswitchIfProfitable(Value *LoopCond, Constant *Val,Loop *L){
return false; 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 // If this is a trivial condition to unswitch (which results in no code
// duplication), do it now. // duplication), do it now.
Constant *CondVal; Constant *CondVal;
@ -456,18 +421,6 @@ BasicBlock *LoopUnswitch::SplitEdge(BasicBlock *BB, BasicBlock *Succ) {
// If the successor only has a single pred, split the top of the successor // If the successor only has a single pred, split the top of the successor
// block. // block.
assert(SP == BB && "CFG broken"); 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()); return SplitBlock(Succ, Succ->begin());
} else { } else {
// Otherwise, if BB has a single successor, split it at the bottom of the // Otherwise, if BB has a single successor, split it at the bottom of the
@ -616,8 +569,8 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
ExitBlocks.erase(std::unique(ExitBlocks.begin(), ExitBlocks.end()), ExitBlocks.erase(std::unique(ExitBlocks.begin(), ExitBlocks.end()),
ExitBlocks.end()); ExitBlocks.end());
// Split all of the edges from inside the loop to their exit blocks. This // Split all of the edges from inside the loop to their exit blocks. Update
// unswitching trivial: no phi nodes to update. // the appropriate Phi nodes as we do so.
unsigned NumBlocks = L->getBlocks().size(); unsigned NumBlocks = L->getBlocks().size();
for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) { for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
@ -627,7 +580,41 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
for (unsigned j = 0, e = Preds.size(); j != e; ++j) { for (unsigned j = 0, e = Preds.size(); j != e; ++j) {
assert(L->contains(Preds[j]) && assert(L->contains(Preds[j]) &&
"All preds of loop exit blocks must be the same loop!"); "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);
}
} }
} }
@ -967,7 +954,30 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
// Found a dead case value. Don't remove PHI nodes in the // Found a dead case value. Don't remove PHI nodes in the
// successor if they become single-entry, those PHI nodes may // successor if they become single-entry, those PHI nodes may
// be in the Users list. // 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); SI->removeCase(i);
break; break;
} }