//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
bool OptimizeForSize;
bool redoLoop;
+
+ DominanceFrontier *DF;
+ DominatorTree *DT;
+
+ /// LoopDF - Loop's dominance frontier. This set is a collection of
+ /// loop exiting blocks' DF member blocks. However this does set does not
+ /// includes basic blocks that are inside loop.
+ SmallPtrSet<BasicBlock *, 8> LoopDF;
+
+ /// OrigLoopExitMap - This is used to map loop exiting block with
+ /// corresponding loop exit block, before updating CFG.
+ DenseMap<BasicBlock *, BasicBlock *> OrigLoopExitMap;
public:
static char ID; // Pass ID, replacement for typeid
explicit LoopUnswitch(bool Os = false) :
if (I != LoopProcessWorklist.end())
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.
+ 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
+ /// remove it. Add NewDFMember in BB's dominance frontier.
+ void ReplaceLoopExternalDFMember(Loop *L, BasicBlock *BB,
+ BasicBlock *NewDFMember);
bool UnswitchIfProfitable(Value *LoopCond, Constant *Val,Loop *L);
unsigned getLoopUnswitchCost(Loop *L, Value *LIC);
if (Value *RHS = FindLIVLoopCondition(BO->getOperand(1), L, Changed))
return RHS;
}
-
- return 0;
+
+ return 0;
}
bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) {
LI = &getAnalysis<LoopInfo>();
LPM = &LPM_Ref;
+ DF = getAnalysisToUpdate<DominanceFrontier>();
+ DT = getAnalysisToUpdate<DominatorTree>();
+
bool Changed = false;
do {
for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
I != E; ++I)
if (LI->getLoopFor(*I) == L)
- New->addBasicBlockToLoop(cast<BasicBlock>(VM[*I]), *LI);
+ New->addBasicBlockToLoop(cast<BasicBlock>(VM[*I]), LI->getBase());
// Add all of the subloops to the new loop.
for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I)
// insert the new conditional branch.
EmitPreheaderBranchOnCondition(Cond, Val, NewExit, NewPH,
OrigPH->getTerminator());
- OrigPH->getTerminator()->eraseFromParent();
LPM->deleteSimpleAnalysisValue(OrigPH->getTerminator(), L);
+ OrigPH->getTerminator()->eraseFromParent();
// We need to reprocess this loop, it could be unswitched again.
redoLoop = true;
++NumTrivial;
}
-/// VersionLoop - We determined that the loop is profitable to unswitch when LIC
-/// equal Val. Split it into loop versions and test the condition outside of
-/// either loop. Return the loops created as Out1/Out2.
-void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
- Loop *L) {
- Function *F = L->getHeader()->getParent();
- DOUT << "loop-unswitch: Unswitching loop %"
- << L->getHeader()->getName() << " [" << L->getBlocks().size()
- << " blocks] in Function " << F->getName()
- << " when '" << *Val << "' == " << *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;
+/// ReplaceLoopExternalDFMember -
+/// 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 LoopUnswitch::ReplaceLoopExternalDFMember(Loop *L, BasicBlock *BB,
+ BasicBlock *NewDFMember) {
+
+ DominanceFrontier::iterator DFI = DF->find(BB);
+ if (DFI == DF->end())
+ return;
+
+ DominanceFrontier::DomSetType &DFSet = DFI->second;
+ for (DominanceFrontier::DomSetType::iterator DI = DFSet.begin(),
+ DE = DFSet.end(); DI != DE;) {
+ BasicBlock *B = *DI++;
+ if (L->contains(B))
+ continue;
- // First step, split the preheader and exit blocks, and add these blocks to
- // the LoopBlocks list.
- BasicBlock *OrigHeader = L->getHeader();
- BasicBlock *OrigPreheader = L->getLoopPreheader();
- BasicBlock *NewPreheader = SplitEdge(OrigPreheader, L->getHeader(), this);
- LoopBlocks.push_back(NewPreheader);
+ DF->removeFromFrontier(DFI, B);
+ LoopDF.insert(B);
+ }
- // We want the loop to come after the preheader, but before the exit blocks.
- LoopBlocks.insert(LoopBlocks.end(), L->block_begin(), L->block_end());
+ DF->addToFrontier(DFI, NewDFMember);
+}
- SmallVector<BasicBlock*, 8> ExitBlocks;
- L->getUniqueExitBlocks(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) {
- // Split all of the edges from inside the loop to their exit blocks. Update
- // the appropriate Phi nodes as we do so.
- SmallVector<BasicBlock *,8> MiddleBlocks;
for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
BasicBlock *ExitBlock = ExitBlocks[i];
std::vector<BasicBlock*> Preds(pred_begin(ExitBlock), pred_end(ExitBlock));
EndBlock = ExitBlock;
}
+ OrigLoopExitMap[StartBlock] = EndBlock;
+
std::set<PHINode*> InsertedPHIs;
PHINode* OldLCSSA = 0;
for (BasicBlock::iterator I = EndBlock->begin();
OldLCSSA->replaceAllUsesWith(NewLCSSA);
NewLCSSA->addIncoming(OldLCSSA, MiddleBlock);
}
+
+ if (DF && DT) {
+ // StartBlock -- > MiddleBlock -- > EndBlock
+ // StartBlock is loop exiting block. EndBlock will become merge point
+ // of two loop exits after loop unswitch.
+
+ // If StartBlock's DF member includes a block that is not loop member
+ // then replace that DF member with EndBlock.
+
+ // If MiddleBlock's DF member includes a block that is not loop member
+ // tnen replace that DF member with EndBlock.
+
+ ReplaceLoopExternalDFMember(L, StartBlock, EndBlock);
+ ReplaceLoopExternalDFMember(L, MiddleBlock, EndBlock);
+ }
}
}
-
+
+}
+
+/// UnswitchNontrivialCondition - We determined that the loop is profitable
+/// to unswitch when LIC equal Val. Split it into loop versions and test the
+/// condition outside of either loop. Return the loops created as Out1/Out2.
+void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
+ Loop *L) {
+ Function *F = L->getHeader()->getParent();
+ DOUT << "loop-unswitch: Unswitching loop %"
+ << L->getHeader()->getName() << " [" << L->getBlocks().size()
+ << " blocks] in Function " << F->getName()
+ << " when '" << *Val << "' == " << *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 *OrigHeader = L->getHeader();
+ BasicBlock *OrigPreheader = L->getLoopPreheader();
+ BasicBlock *NewPreheader = SplitEdge(OrigPreheader, L->getHeader(), this);
+ LoopBlocks.push_back(NewPreheader);
+
+ // We want the loop to come after the preheader, but before the exit blocks.
+ LoopBlocks.insert(LoopBlocks.end(), L->block_begin(), L->block_end());
+
+ SmallVector<BasicBlock*, 8> ExitBlocks;
+ L->getUniqueExitBlocks(ExitBlocks);
+
+ // Split all of the edges from inside the loop to their exit blocks. Update
+ // the appropriate Phi nodes as we do so.
+ SmallVector<BasicBlock *,8> MiddleBlocks;
+ SplitExitEdges(L, ExitBlocks, MiddleBlocks);
+
// The exit blocks may have been changed due to edge splitting, recompute.
ExitBlocks.clear();
L->getUniqueExitBlocks(ExitBlocks);
// Add exit blocks to the loop blocks.
LoopBlocks.insert(LoopBlocks.end(), ExitBlocks.begin(), ExitBlocks.end());
- DominanceFrontier *DF = getAnalysisToUpdate<DominanceFrontier>();
- DominatorTree *DT = getAnalysisToUpdate<DominatorTree>();
-
// 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
// the instructions and blocks.
if (ParentLoop) {
// Make sure to add the cloned preheader and exit blocks to the parent loop
// as well.
- ParentLoop->addBasicBlockToLoop(NewBlocks[0], *LI);
+ ParentLoop->addBasicBlockToLoop(NewBlocks[0], LI->getBase());
}
for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
BasicBlock *NewExit = cast<BasicBlock>(ValueMap[ExitBlocks[i]]);
// The new exit block should be in the same loop as the old one.
if (Loop *ExitBBLoop = LI->getLoopFor(ExitBlocks[i]))
- ExitBBLoop->addBasicBlockToLoop(NewExit, *LI);
+ ExitBBLoop->addBasicBlockToLoop(NewExit, LI->getBase());
assert(NewExit->getTerminator()->getNumSuccessors() == 1 &&
"Exit block should have been split to have one successor!");
// Emit the new branch that selects between the two versions of this loop.
EmitPreheaderBranchOnCondition(LIC, Val, NewBlocks[0], LoopBlocks[0], OldBR);
- OldBR->eraseFromParent();
LPM->deleteSimpleAnalysisValue(OldBR, L);
+ OldBR->eraseFromParent();
// Update dominator info
if (DF && DT) {
+ SmallVector<BasicBlock *,4> ExitingBlocks;
+ L->getExitingBlocks(ExitingBlocks);
+
// Clone dominator info for all cloned basic block.
for (unsigned i = 0, e = LoopBlocks.size(); i != e; ++i) {
BasicBlock *LBB = LoopBlocks[i];
CloneDomInfo(NBB, LBB, NewPreheader, OrigPreheader,
OrigHeader, DT, DF, ValueMap);
- // Remove any OutSiders from LBB and NBB's dominance frontier.
- DominanceFrontier::iterator LBBI = DF->find(LBB);
- if (LBBI != DF->end()) {
- DominanceFrontier::DomSetType &LBSet = LBBI->second;
- for (DominanceFrontier::DomSetType::iterator LI = LBSet.begin(),
- LE = LBSet.end(); LI != LE; /* NULL */) {
- BasicBlock *B = *LI++;
- if (OutSiders.count(B))
- DF->removeFromFrontier(LBBI, B);
- }
- }
+ // 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
- // Remove any OutSiders from LBB and NBB's dominance frontier.
+ DominanceFrontier::iterator LBBI = DF->find(LBB);
DominanceFrontier::iterator NBBI = DF->find(NBB);
- if (NBBI != DF->end()) {
- DominanceFrontier::DomSetType NBSet = NBBI->second;
- for (DominanceFrontier::DomSetType::iterator NI = NBSet.begin(),
- NE = NBSet.end(); NI != NE; /* NULL */) {
- BasicBlock *B = *NI++;
- if (OutSiders.count(B))
+ if (LBBI == DF->end())
+ continue;
+
+ DominanceFrontier::DomSetType &LBSet = LBBI->second;
+ for (DominanceFrontier::DomSetType::iterator LI = LBSet.begin(),
+ LE = LBSet.end(); LI != LE; /* NULL */) {
+ BasicBlock *B = *LI++;
+ if (B == LBB && B == L->getHeader())
+ continue;
+ bool removeB = false;
+ if (!LoopDF.count(B))
+ continue;
+
+ // If LBB dominates loop exits then insert loop exit block's DF
+ // into B's DF.
+ for(SmallVector<BasicBlock *, 4>::iterator LExitI = ExitingBlocks.begin(),
+ LExitE = ExitingBlocks.end(); LExitI != LExitE; ++LExitI) {
+ BasicBlock *E = *LExitI;
+
+ if (!DT->dominates(LBB,E))
+ continue;
+
+ DenseMap<BasicBlock *, BasicBlock *>::iterator DFBI =
+ OrigLoopExitMap.find(E);
+ if (DFBI == OrigLoopExitMap.end())
+ continue;
+
+ BasicBlock *DFB = DFBI->second;
+ DF->addToFrontier(LBBI, DFB);
+ DF->addToFrontier(NBBI, DFB);
+ removeB = true;
+ }
+
+ // 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))
+ DF->removeFromFrontier(NBBI, cast<BasicBlock>(ValueMap[B]));
+ else
DF->removeFromFrontier(NBBI, B);
}
}
+
}
// MiddleBlocks are dominated by original pre header. SplitEdge updated
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
UI != E; ++UI)
Worklist.push_back(cast<Instruction>(*UI));
- I->replaceAllUsesWith(V);
- I->eraseFromParent();
LPM->deleteSimpleAnalysisValue(I, L);
RemoveFromWorklist(I, Worklist);
+ I->replaceAllUsesWith(V);
+ I->eraseFromParent();
++NumSimplify;
}
// Remove the branch from the latch to the header block, this makes
// the header dead, which will make the latch dead (because the header
// dominates the latch).
- Pred->getTerminator()->eraseFromParent();
LPM->deleteSimpleAnalysisValue(Pred->getTerminator(), L);
+ Pred->getTerminator()->eraseFromParent();
new UnreachableInst(Pred);
// The loop is now broken, remove it from LI.
Succs.erase(std::unique(Succs.begin(), Succs.end()), Succs.end());
// Remove the basic block, including all of the instructions contained in it.
- BB->eraseFromParent();
LPM->deleteSimpleAnalysisValue(BB, L);
+ BB->eraseFromParent();
// Remove successor blocks here that are not dead, so that we know we only
// have dead blocks in this list. Nondead blocks have a way of becoming dead,
// then getting removed before we revisit them, which is badness.
Instruction* OldTerm = Old->getTerminator();
new BranchInst(Split, SI->getSuccessor(i),
ConstantInt::getTrue(), OldTerm);
-
+
+ LPM->deleteSimpleAnalysisValue(Old->getTerminator(), L);
Old->getTerminator()->eraseFromParent();
-
PHINode *PN;
for (BasicBlock::iterator II = SI->getSuccessor(i)->begin();
(PN = dyn_cast<PHINode>(II)); ++II) {
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
if (Instruction *Use = dyn_cast<Instruction>(I->getOperand(i)))
Worklist.push_back(Use);
- I->eraseFromParent();
LPM->deleteSimpleAnalysisValue(I, L);
RemoveFromWorklist(I, Worklist);
+ I->eraseFromParent();
++NumSimplify;
continue;
}
// Move all of the successor contents from Succ to Pred.
Pred->getInstList().splice(BI, Succ->getInstList(), Succ->begin(),
Succ->end());
- BI->eraseFromParent();
LPM->deleteSimpleAnalysisValue(BI, L);
+ BI->eraseFromParent();
RemoveFromWorklist(BI, Worklist);
// If Succ has any successors with PHI nodes, update them to have
// Remove Succ from the loop tree.
LI->removeBlock(Succ);
- Succ->eraseFromParent();
LPM->deleteSimpleAnalysisValue(Succ, L);
+ Succ->eraseFromParent();
++NumSimplify;
} else if (ConstantInt *CB = dyn_cast<ConstantInt>(BI->getCondition())){
// Conditional branch. Turn it into an unconditional branch, then
BasicBlock *LiveSucc = BI->getSuccessor(!CB->getZExtValue());
DeadSucc->removePredecessor(BI->getParent(), true);
Worklist.push_back(new BranchInst(LiveSucc, BI));
- BI->eraseFromParent();
LPM->deleteSimpleAnalysisValue(BI, L);
+ BI->eraseFromParent();
RemoveFromWorklist(BI, Worklist);
++NumSimplify;