STATISTIC(NumTrivial , "Number of unswitches that are trivial");
STATISTIC(NumSimplify, "Number of simplifications of unswitched code");
-namespace {
- cl::opt<unsigned>
- Threshold("loop-unswitch-threshold", cl::desc("Max loop size to unswitch"),
- cl::init(10), cl::Hidden);
+static cl::opt<unsigned>
+Threshold("loop-unswitch-threshold", cl::desc("Max loop size to unswitch"),
+ cl::init(10), cl::Hidden);
+namespace {
class VISIBILITY_HIDDEN LoopUnswitch : public LoopPass {
LoopInfo *LI; // Loop information
LPPassManager *LPM;
LoopProcessWorklist.erase(I);
}
- /// Split all of the edges from inside the loop to their exit blocks. Update
- /// the appropriate Phi nodes as we do so.
+ /// Split all of the edges from inside the loop to their exit blocks.
+ /// Update the appropriate Phi nodes as we do so.
void SplitExitEdges(Loop *L, const SmallVector<BasicBlock *, 8> &ExitBlocks,
SmallVector<BasicBlock *, 8> &MiddleBlocks);
- /// If BB's dominance frontier has a member that is not part of loop L then
+ /// If BB's dominance frontier has a member that is not part of loop L then
/// remove it. Add NewDFMember in BB's dominance frontier.
void ReplaceLoopExternalDFMember(Loop *L, BasicBlock *BB,
BasicBlock *NewDFMember);
std::vector<Instruction*> &Worklist, Loop *l);
void RemoveLoopFromHierarchy(Loop *L);
};
- char LoopUnswitch::ID = 0;
- RegisterPass<LoopUnswitch> X("loop-unswitch", "Unswitch loops");
}
+char LoopUnswitch::ID = 0;
+static RegisterPass<LoopUnswitch> X("loop-unswitch", "Unswitch loops");
LoopPass *llvm::createLoopUnswitchPass(bool Os) {
return new LoopUnswitch(Os);
// OrigPreheader is loop pre-header before this pass started
// updating CFG. NewPrehader is loops new pre-header. However, after CFG
// manipulation, loop L may not exist. So rely on input parameter NewPreheader.
-void CloneDomInfo(BasicBlock *NewBB, BasicBlock *Orig,
- BasicBlock *NewPreheader, BasicBlock *OrigPreheader,
- BasicBlock *OrigHeader,
- DominatorTree *DT, DominanceFrontier *DF,
- DenseMap<const Value*, Value*> &VM) {
+static void CloneDomInfo(BasicBlock *NewBB, BasicBlock *Orig,
+ BasicBlock *NewPreheader, BasicBlock *OrigPreheader,
+ BasicBlock *OrigHeader,
+ DominatorTree *DT, DominanceFrontier *DF,
+ DenseMap<const Value*, Value*> &VM) {
// If NewBB alreay has found its place in domiantor tree then no need to do
// anything.
std::swap(TrueDest, FalseDest);
// Insert the new branch.
- new BranchInst(TrueDest, FalseDest, BranchVal, InsertPt);
-
+ BranchInst::Create(TrueDest, FalseDest, BranchVal, InsertPt);
}
// insert the new conditional branch.
EmitPreheaderBranchOnCondition(Cond, Val, NewExit, NewPH,
OrigPH->getTerminator());
+ if (DT) {
+ DT->changeImmediateDominator(NewExit, OrigPH);
+ DT->changeImmediateDominator(NewPH, OrigPH);
+ }
+
+ if (DF) {
+ // NewExit is now part of NewPH and Loop Header's dominance
+ // frontier.
+ DominanceFrontier::iterator DFI = DF->find(NewPH);
+ if (DFI != DF->end())
+ DF->addToFrontier(DFI, NewExit);
+ DFI = DF->find(L->getHeader());
+ DF->addToFrontier(DFI, NewExit);
+
+ // ExitBlock does not have successors then NewExit is part of
+ // its dominance frontier.
+ if (succ_begin(ExitBlock) == succ_end(ExitBlock)) {
+ DFI = DF->find(ExitBlock);
+ DF->addToFrontier(DFI, NewExit);
+ }
+ }
LPM->deleteSimpleAnalysisValue(OrigPH->getTerminator(), L);
OrigPH->getTerminator()->eraseFromParent();
DF->addToFrontier(DFI, NewDFMember);
}
-/// SplitExitEdges -
-/// Split all of the edges from inside the loop to their exit blocks. Update
-/// the appropriate Phi nodes as we do so.
-void LoopUnswitch::SplitExitEdges(Loop *L, const SmallVector<BasicBlock *, 8> &ExitBlocks,
+/// SplitExitEdges - Split all of the edges from inside the loop to their exit
+/// blocks. Update the appropriate Phi nodes as we do so.
+void LoopUnswitch::SplitExitEdges(Loop *L,
+ const SmallVector<BasicBlock *, 8> &ExitBlocks,
SmallVector<BasicBlock *, 8> &MiddleBlocks) {
for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
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());
+ PHINode* NewLCSSA = PHINode::Create(OldLCSSA->getType(),
+ OldLCSSA->getName() + ".us-lcssa",
+ MiddleBlock->getTerminator());
NewLCSSA->addIncoming(OldValue, StartBlock);
OldLCSSA->setIncomingValue(OldLCSSA->getBasicBlockIndex(MiddleBlock),
NewLCSSA);
InsertedPHIs.insert(NewLCSSA);
}
- BasicBlock::iterator InsertPt = EndBlock->begin();
- while (dyn_cast<PHINode>(InsertPt)) ++InsertPt;
+ BasicBlock::iterator InsertPt = EndBlock->getFirstNonPHI();
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);
+ PHINode *NewLCSSA = PHINode::Create(OldLCSSA->getType(),
+ OldLCSSA->getName() + ".us-lcssa",
+ InsertPt);
OldLCSSA->replaceAllUsesWith(NewLCSSA);
NewLCSSA->addIncoming(OldLCSSA, MiddleBlock);
}
}
// Rewrite the code to refer to itself.
- for (unsigned i = 0, e = NewBlocks.size(); i != e; ++i) {
- BasicBlock *NB = NewBlocks[i];
- if (BasicBlock *UnwindDest = NB->getUnwindDest())
- NB->setUnwindDest(cast<BasicBlock>(ValueMap[UnwindDest]));
-
- for (BasicBlock::iterator I = NB->begin(), E = NB->end(); I != E; ++I)
+ for (unsigned i = 0, e = NewBlocks.size(); i != e; ++i)
+ for (BasicBlock::iterator I = NewBlocks[i]->begin(),
+ E = NewBlocks[i]->end(); I != E; ++I)
RemapInstruction(I, ValueMap);
- }
// Rewrite the original preheader to select between versions of the loop.
BranchInst *OldBR = cast<BranchInst>(OrigPreheader->getTerminator());
// If LBB's dominance frontier includes DFMember
// such that DFMember is also a member of LoopDF then
// - Remove DFMember from LBB's dominance frontier
- // - Copy loop exiting blocks', that are dominated by BB, dominance frontier
- // member in BB's dominance frontier
+ // - Copy loop exiting blocks', that are dominated by BB,
+ // dominance frontier member in BB's dominance frontier
DominanceFrontier::iterator LBBI = DF->find(LBB);
DominanceFrontier::iterator NBBI = DF->find(NBB);
// If LBB dominates loop exits then insert loop exit block's DF
// into B's DF.
- for(SmallVector<BasicBlock *, 4>::iterator LExitI = ExitingBlocks.begin(),
+ for(SmallVector<BasicBlock *, 4>::iterator
+ LExitI = ExitingBlocks.begin(),
LExitE = ExitingBlocks.end(); LExitI != LExitE; ++LExitI) {
BasicBlock *E = *LExitI;
removeB = true;
}
- // If B's replacement is inserted in DF then now is the time to remove B.
+ // If B's replacement is inserted in DF then now is the time to remove
+ // B.
if (removeB) {
DF->removeFromFrontier(LBBI, B);
if (L->contains(B))
BasicBlock* Split = SplitBlock(Old, SI, this);
Instruction* OldTerm = Old->getTerminator();
- new BranchInst(Split, SI->getSuccessor(i),
- ConstantInt::getTrue(), OldTerm);
+ BranchInst::Create(Split, SI->getSuccessor(i),
+ ConstantInt::getTrue(), OldTerm);
- LPM->deleteSimpleAnalysisValue(Old->getTerminator(), L);
+ LPM->deleteSimpleAnalysisValue(Old->getTerminator(), L);
Old->getTerminator()->eraseFromParent();
PHINode *PN;
BasicBlock *DeadSucc = BI->getSuccessor(CB->getZExtValue());
BasicBlock *LiveSucc = BI->getSuccessor(!CB->getZExtValue());
DeadSucc->removePredecessor(BI->getParent(), true);
- Worklist.push_back(new BranchInst(LiveSucc, BI));
+ Worklist.push_back(BranchInst::Create(LiveSucc, BI));
LPM->deleteSimpleAnalysisValue(BI, L);
BI->eraseFromParent();
RemoveFromWorklist(BI, Worklist);