aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2007-07-18 23:48:20 +0000
committerDevang Patel <dpatel@apple.com>2007-07-18 23:48:20 +0000
commit31ad75329ec8e1e3806dc767038678ce8eedb638 (patch)
treeceb393680900e63e47871cc8a026154ea2a6987d /lib
parenta8d507d97062620669fbe6ced305b920eb0344ef (diff)
downloadexternal_llvm-31ad75329ec8e1e3806dc767038678ce8eedb638.zip
external_llvm-31ad75329ec8e1e3806dc767038678ce8eedb638.tar.gz
external_llvm-31ad75329ec8e1e3806dc767038678ce8eedb638.tar.bz2
Fix dominator info update to accommodate CFG changes.
This fixes PR1559. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40024 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/Scalar/LoopUnswitch.cpp82
1 files changed, 65 insertions, 17 deletions
diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp
index c433e63..bd9d026 100644
--- a/lib/Transforms/Scalar/LoopUnswitch.cpp
+++ b/lib/Transforms/Scalar/LoopUnswitch.cpp
@@ -408,26 +408,70 @@ static inline void RemapInstruction(Instruction *I,
}
// CloneDomInfo - NewBB is cloned from Orig basic block. Now clone Dominator Info.
-// If Orig is in Loop then find and use Orig dominator's cloned block as NewBB
-// dominator.
-void CloneDomInfo(BasicBlock *NewBB, BasicBlock *Orig, Loop *L,
+//
+// If Orig block's immediate dominator is mapped in VM then use corresponding
+// immediate dominator from the map. Otherwise Orig block's dominator is also
+// NewBB's dominator.
+//
+// OrigPreheader is loop pre-header before this patch started
+// updating CFG. NewPrehader is loops new pre-header. However, after CFG
+// manipulation, loop L may not exist. So rely in input parameter NewPreheader.
+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.
+ if (DT->getNode(NewBB))
+ return;
+
+ // If Orig does not have any immediate domiantor then its clone, NewBB, does
+ // not need any immediate dominator.
DomTreeNode *OrigNode = DT->getNode(Orig);
if (!OrigNode)
return;
- BasicBlock *OrigIDom = OrigNode->getBlock();
- BasicBlock *NewIDom = OrigIDom;
- if (L->contains(OrigIDom)) {
- if (!DT->getNode(OrigIDom))
- CloneDomInfo(NewIDom, OrigIDom, L, DT, DF, VM);
- NewIDom = cast<BasicBlock>(VM[OrigIDom]);
+ DomTreeNode *OrigIDomNode = OrigNode->getIDom();
+ if (!OrigIDomNode)
+ return;
+
+ BasicBlock *OrigIDom = NULL;
+
+ // If Orig is original loop header then its immediate dominator is
+ // NewPreheader.
+ if (Orig == OrigHeader)
+ OrigIDom = NewPreheader;
+
+ // If Orig is new pre-header then its immediate dominator is
+ // original pre-header.
+ else if (Orig == NewPreheader)
+ OrigIDom = OrigPreheader;
+
+ // Other as DT to find Orig's immediate dominator.
+ else
+ OrigIDom = OrigIDomNode->getBlock();
+
+ // Initially use Orig's immediate dominator as NewBB's immediate dominator.
+ BasicBlock *NewIDom = OrigIDom;
+ DenseMap<const Value*, Value*>::iterator I = VM.find(OrigIDom);
+ if (I != VM.end()) {
+ // if (!DT->getNode(OrigIDom))
+ // CloneDomInfo(NewIDom, OrigIDom, NewPreheader, OrigPreheader,
+ // OrigHeader, DT, DF, VM);
+
+ NewIDom = cast<BasicBlock>(I->second);
+
+ // If NewIDom does not have corresponding dominatore tree node then
+ // get one.
+ if (!DT->getNode(NewIDom))
+ CloneDomInfo(NewIDom, OrigIDom, NewPreheader, OrigPreheader,
+ OrigHeader, DT, DF, VM);
}
- if (NewBB == NewIDom) {
- DT->addNewBlock(NewBB, OrigIDom);
- DT->changeImmediateDominator(NewBB, NewIDom);
- } else
+ // if (NewBB == NewIDom) {
+ // DT->addNewBlock(NewBB, OrigIDom);
+ // DT->changeImmediateDominator(NewBB, NewIDom);
+ //} else
DT->addNewBlock(NewBB, NewIDom);
DominanceFrontier::DomSetType NewDFSet;
@@ -438,8 +482,9 @@ void CloneDomInfo(BasicBlock *NewBB, BasicBlock *Orig, Loop *L,
for (DominanceFrontier::DomSetType::iterator I = S.begin(), E = S.end();
I != E; ++I) {
BasicBlock *BB = *I;
- if (L->contains(BB))
- NewDFSet.insert(cast<BasicBlock>(VM[Orig]));
+ DenseMap<const Value*, Value*>::iterator I = VM.find(BB);
+ if (I != VM.end())
+ NewDFSet.insert(cast<BasicBlock>(I->second));
else
NewDFSet.insert(BB);
}
@@ -564,8 +609,10 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
// First step, split the preheader and exit blocks, and add these blocks to
// the LoopBlocks list.
+ BasicBlock *OrigHeader = L->getHeader();
BasicBlock *OrigPreheader = L->getLoopPreheader();
- LoopBlocks.push_back(SplitEdge(OrigPreheader, L->getHeader(), this));
+ 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());
@@ -643,7 +690,8 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
for (unsigned i = 0, e = LoopBlocks.size(); i != e; ++i) {
BasicBlock *LBB = LoopBlocks[i];
BasicBlock *NBB = NewBlocks[i];
- CloneDomInfo(NBB, LBB, L, DT, DF, ValueMap);
+ CloneDomInfo(NBB, LBB, NewPreheader, OrigPreheader,
+ OrigHeader, DT, DF, ValueMap);
}
// Splice the newly inserted blocks into the function right before the