summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2007-08-17 21:59:16 +0000
committerDevang Patel <dpatel@apple.com>2007-08-17 21:59:16 +0000
commit96bf524b531fd404b118fad7bbe410e9aceeaa5d (patch)
treebe25bf6cf25aae8fdc046f23c8aeabc6eaf31d6d
parent3e20bba5eb5df2fdd3e6655c8470084cf05032d4 (diff)
downloadllvm-96bf524b531fd404b118fad7bbe410e9aceeaa5d.tar.gz
llvm-96bf524b531fd404b118fad7bbe410e9aceeaa5d.tar.bz2
llvm-96bf524b531fd404b118fad7bbe410e9aceeaa5d.tar.xz
When one branch of condition is eliminated then head of the other
branch is not necessary immediate dominators of merge blcok in all cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41144 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Analysis/Dominators.h20
-rw-r--r--lib/Transforms/Scalar/LoopIndexSplit.cpp63
-rw-r--r--lib/Transforms/Utils/LCSSA.cpp3
3 files changed, 64 insertions, 22 deletions
diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h
index 41e6938459..ec6a67b60d 100644
--- a/include/llvm/Analysis/Dominators.h
+++ b/include/llvm/Analysis/Dominators.h
@@ -438,6 +438,26 @@ public:
/// frontier to reflect this change.
void splitBlock(BasicBlock *BB);
+ /// BasicBlock BB's new dominator is NewBB. Update BB's dominance frontier
+ /// to reflect this change.
+ void changeImmediateDominator(BasicBlock *BB, BasicBlock *NewBB,
+ DominatorTree *DT) {
+ // NewBB is now dominating BB. Which means BB's dominance
+ // frontier is now part of NewBB's dominance frontier. However, BB
+ // itself is not member of NewBB's dominance frontier.
+ DominanceFrontier::iterator NewDFI = find(NewBB);
+ DominanceFrontier::iterator DFI = find(BB);
+ DominanceFrontier::DomSetType BBSet = DFI->second;
+ for (DominanceFrontier::DomSetType::iterator BBSetI = BBSet.begin(),
+ BBSetE = BBSet.end(); BBSetI != BBSetE; ++BBSetI) {
+ BasicBlock *DFMember = *BBSetI;
+ // Insert only if NewBB dominates DFMember.
+ if (!DT->dominates(NewBB, DFMember))
+ NewDFI->second.insert(DFMember);
+ }
+ NewDFI->second.erase(BB);
+ }
+
private:
const DomSetType &calculate(const DominatorTree &DT,
const DomTreeNode *Node);
diff --git a/lib/Transforms/Scalar/LoopIndexSplit.cpp b/lib/Transforms/Scalar/LoopIndexSplit.cpp
index 565e00c895..980990ea65 100644
--- a/lib/Transforms/Scalar/LoopIndexSplit.cpp
+++ b/lib/Transforms/Scalar/LoopIndexSplit.cpp
@@ -603,6 +603,7 @@ void LoopIndexSplit::removeBlocks(BasicBlock *DeadBB, Loop *LP,
BasicBlock *LiveBB) {
// First update DeadBB's dominance frontier.
+ SmallVector<BasicBlock *, 8> FrontierBBs;
DominanceFrontier::iterator DeadBBDF = DF->find(DeadBB);
if (DeadBBDF != DF->end()) {
SmallVector<BasicBlock *, 8> PredBlocks;
@@ -611,7 +612,8 @@ void LoopIndexSplit::removeBlocks(BasicBlock *DeadBB, Loop *LP,
for (DominanceFrontier::DomSetType::iterator DeadBBSetI = DeadBBSet.begin(),
DeadBBSetE = DeadBBSet.end(); DeadBBSetI != DeadBBSetE; ++DeadBBSetI) {
BasicBlock *FrontierBB = *DeadBBSetI;
-
+ FrontierBBs.push_back(FrontierBB);
+
// Rremove any PHI incoming edge from blocks dominated by DeadBB.
PredBlocks.clear();
for(pred_iterator PI = pred_begin(FrontierBB), PE = pred_end(FrontierBB);
@@ -620,7 +622,8 @@ void LoopIndexSplit::removeBlocks(BasicBlock *DeadBB, Loop *LP,
if (P == DeadBB || DT->dominates(DeadBB, P))
PredBlocks.push_back(P);
}
-
+
+ BasicBlock *NewDominator = NULL;
for(BasicBlock::iterator FBI = FrontierBB->begin(), FBE = FrontierBB->end();
FBI != FBE; ++FBI) {
if (PHINode *PN = dyn_cast<PHINode>(FBI)) {
@@ -629,27 +632,14 @@ void LoopIndexSplit::removeBlocks(BasicBlock *DeadBB, Loop *LP,
BasicBlock *P = *PI;
PN->removeIncomingValue(P);
}
+ // If we have not identified new dominator then see if we can identify
+ // one based on remaining incoming PHINode values.
+ if (NewDominator == NULL && PN->getNumIncomingValues() == 1)
+ NewDominator = PN->getIncomingBlock(0);
}
else
break;
- }
-
- DT->changeImmediateDominator(FrontierBB, LiveBB);
-
- // LiveBB is now dominating FrontierBB. Which means FrontierBB's dominance
- // frontier is member of LiveBB's dominance frontier. However, FrontierBB
- // itself is not member of LiveBB's dominance frontier.
- DominanceFrontier::iterator LiveDF = DF->find(LiveBB);
- DominanceFrontier::iterator FrontierDF = DF->find(FrontierBB);
- DominanceFrontier::DomSetType FrontierBBSet = FrontierDF->second;
- for (DominanceFrontier::DomSetType::iterator FrontierBBSetI = FrontierBBSet.begin(),
- FrontierBBSetE = FrontierBBSet.end(); FrontierBBSetI != FrontierBBSetE; ++FrontierBBSetI) {
- BasicBlock *DFMember = *FrontierBBSetI;
- // Insert only if LiveBB dominates DFMember.
- if (!DT->dominates(LiveBB, DFMember))
- LiveDF->second.insert(DFMember);
- }
- LiveDF->second.erase(FrontierBB);
+ }
}
}
@@ -660,7 +650,7 @@ void LoopIndexSplit::removeBlocks(BasicBlock *DeadBB, Loop *LP,
E = df_end(DN); DI != E; ++DI) {
BasicBlock *BB = DI->getBlock();
WorkList.push_back(BB);
- BB->getTerminator()->eraseFromParent();
+ BB->replaceAllUsesWith(UndefValue::get(Type::LabelTy));
}
while (!WorkList.empty()) {
@@ -677,6 +667,31 @@ void LoopIndexSplit::removeBlocks(BasicBlock *DeadBB, Loop *LP,
LI->removeBlock(BB);
BB->eraseFromParent();
}
+
+ // Update Frontier BBs' dominator info.
+ while (!FrontierBBs.empty()) {
+ BasicBlock *FBB = FrontierBBs.back(); FrontierBBs.pop_back();
+ BasicBlock *NewDominator = FBB->getSinglePredecessor();
+ if (!NewDominator) {
+ pred_iterator PI = pred_begin(FBB), PE = pred_end(FBB);
+ NewDominator = *PI;
+ ++PI;
+ if (NewDominator != LiveBB) {
+ for(; PI != PE; ++PI) {
+ BasicBlock *P = *PI;
+ if (P == LiveBB) {
+ NewDominator = LiveBB;
+ break;
+ }
+ NewDominator = DT->findNearestCommonDominator(NewDominator, P);
+ }
+ }
+ }
+ assert (NewDominator && "Unable to fix dominator info.");
+ DT->changeImmediateDominator(FBB, NewDominator);
+ DF->changeImmediateDominator(FBB, NewDominator, DT);
+ }
+
}
bool LoopIndexSplit::splitLoop(SplitInfo &SD) {
@@ -696,6 +711,12 @@ bool LoopIndexSplit::splitLoop(SplitInfo &SD) {
|| Latch == SplitTerminator->getSuccessor(1)))
return false;
+
+ BasicBlock *Succ0 = SplitTerminator->getSuccessor(0);
+ BasicBlock *Succ1 = SplitTerminator->getSuccessor(1);
+ if (DT->dominates(Succ0, Latch) || DT->dominates(Succ1, Latch))
+ return false;
+
// True loop is original loop. False loop is cloned loop.
bool SignedPredicate = ExitCondition->isSignedPredicate();
diff --git a/lib/Transforms/Utils/LCSSA.cpp b/lib/Transforms/Utils/LCSSA.cpp
index 466136dea7..465214cba9 100644
--- a/lib/Transforms/Utils/LCSSA.cpp
+++ b/lib/Transforms/Utils/LCSSA.cpp
@@ -107,7 +107,8 @@ bool LCSSA::runOnLoop(Loop *L, LPPassManager &LPM) {
LI = &LPM.getAnalysis<LoopInfo>();
DT = &getAnalysis<DominatorTree>();
-
+ DominanceFrontier *DF = getAnalysisToUpdate<DominanceFrontier>();
+
// Speed up queries by creating a sorted list of blocks
LoopBlocks.clear();
LoopBlocks.insert(LoopBlocks.end(), L->block_begin(), L->block_end());