[llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp

Devang Patel dpatel at apple.com
Thu Jun 21 10:24:15 PDT 2007



Changes in directory llvm/lib/VMCore:

Dominators.cpp updated: 1.117 -> 1.118
---
Log message:

Move code to update dominator information after basic block is split
from LoopSimplify.cpp to Dominator.cpp


---
Diffs of the changes:  (+184 -0)

 Dominators.cpp |  184 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 184 insertions(+)


Index: llvm/lib/VMCore/Dominators.cpp
diff -u llvm/lib/VMCore/Dominators.cpp:1.117 llvm/lib/VMCore/Dominators.cpp:1.118
--- llvm/lib/VMCore/Dominators.cpp:1.117	Tue Jun 12 12:50:25 2007
+++ llvm/lib/VMCore/Dominators.cpp	Thu Jun 21 12:23:45 2007
@@ -63,6 +63,89 @@
 static RegisterPass<DominatorTree>
 E("domtree", "Dominator Tree Construction", true);
 
+// NewBB is split and now it has one successor. Update dominator tree to
+// reflect this change.
+void DominatorTree::splitBlock(BasicBlock *NewBB) {
+
+  assert(NewBB->getTerminator()->getNumSuccessors() == 1
+         && "NewBB should have a single successor!");
+  BasicBlock *NewBBSucc = NewBB->getTerminator()->getSuccessor(0);
+
+  std::vector<BasicBlock*> PredBlocks;
+  for (pred_iterator PI = pred_begin(NewBB), PE = pred_end(NewBB);
+       PI != PE; ++PI)
+      PredBlocks.push_back(*PI);  
+
+  assert(!PredBlocks.empty() && "No predblocks??");
+
+  // The newly inserted basic block will dominate existing basic blocks iff the
+  // PredBlocks dominate all of the non-pred blocks.  If all predblocks dominate
+  // the non-pred blocks, then they all must be the same block!
+  //
+  bool NewBBDominatesNewBBSucc = true;
+  {
+    BasicBlock *OnePred = PredBlocks[0];
+    unsigned i = 1, e = PredBlocks.size();
+    for (i = 1; !isReachableFromEntry(OnePred); ++i) {
+      assert(i != e && "Didn't find reachable pred?");
+      OnePred = PredBlocks[i];
+    }
+    
+    for (; i != e; ++i)
+      if (PredBlocks[i] != OnePred && isReachableFromEntry(OnePred)){
+        NewBBDominatesNewBBSucc = false;
+        break;
+      }
+
+    if (NewBBDominatesNewBBSucc)
+      for (pred_iterator PI = pred_begin(NewBBSucc), E = pred_end(NewBBSucc);
+           PI != E; ++PI)
+        if (*PI != NewBB && !dominates(NewBBSucc, *PI)) {
+          NewBBDominatesNewBBSucc = false;
+          break;
+        }
+  }
+
+  // The other scenario where the new block can dominate its successors are when
+  // all predecessors of NewBBSucc that are not NewBB are dominated by NewBBSucc
+  // already.
+  if (!NewBBDominatesNewBBSucc) {
+    NewBBDominatesNewBBSucc = true;
+    for (pred_iterator PI = pred_begin(NewBBSucc), E = pred_end(NewBBSucc);
+         PI != E; ++PI)
+      if (*PI != NewBB && !dominates(NewBBSucc, *PI)) {
+        NewBBDominatesNewBBSucc = false;
+        break;
+      }
+  }
+
+
+  // Find NewBB's immediate dominator and create new dominator tree node for NewBB.
+  BasicBlock *NewBBIDom = 0;
+  unsigned i = 0;
+  for (i = 0; i < PredBlocks.size(); ++i)
+    if (isReachableFromEntry(PredBlocks[i])) {
+      NewBBIDom = PredBlocks[i];
+      break;
+    }
+  assert(i != PredBlocks.size() && "No reachable preds?");
+  for (i = i + 1; i < PredBlocks.size(); ++i) {
+    if (isReachableFromEntry(PredBlocks[i]))
+      NewBBIDom = findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
+  }
+  assert(NewBBIDom && "No immediate dominator found??");
+  
+  // Create the new dominator tree node... and set the idom of NewBB.
+  DomTreeNode *NewBBNode = addNewBlock(NewBB, NewBBIDom);
+  
+  // If NewBB strictly dominates other blocks, then it is now the immediate
+  // dominator of NewBBSucc.  Update the dominator tree as appropriate.
+  if (NewBBDominatesNewBBSucc) {
+    DomTreeNode *NewBBSuccNode = getNode(NewBBSucc);
+    changeImmediateDominator(NewBBSuccNode, NewBBNode);
+  }
+}
+
 unsigned DominatorTree::DFSPass(BasicBlock *V, InfoRec &VInfo,
                                       unsigned N) {
   // This is more understandable as a recursive algorithm, but we can't use the
@@ -520,6 +603,107 @@
 static RegisterPass<DominanceFrontier>
 G("domfrontier", "Dominance Frontier Construction", true);
 
+// NewBB is split and now it has one successor. Update dominace frontier to
+// reflect this change.
+void DominanceFrontier::splitBlock(BasicBlock *NewBB) {
+
+  assert(NewBB->getTerminator()->getNumSuccessors() == 1
+         && "NewBB should have a single successor!");
+  BasicBlock *NewBBSucc = NewBB->getTerminator()->getSuccessor(0);
+
+  std::vector<BasicBlock*> PredBlocks;
+  for (pred_iterator PI = pred_begin(NewBB), PE = pred_end(NewBB);
+       PI != PE; ++PI)
+      PredBlocks.push_back(*PI);  
+
+  assert(!PredBlocks.empty() && "No predblocks??");
+
+  DominatorTree &DT = getAnalysis<DominatorTree>();
+  bool NewBBDominatesNewBBSucc = true;
+  if (!DT.dominates(NewBB, NewBBSucc))
+    NewBBDominatesNewBBSucc = false;
+
+  // If NewBB dominates NewBBSucc, then DF(NewBB) is now going to be the
+  // DF(PredBlocks[0]) without the stuff that the new block does not dominate
+  // a predecessor of.
+  if (NewBBDominatesNewBBSucc) {
+    DominanceFrontier::iterator DFI = find(PredBlocks[0]);
+    if (DFI != end()) {
+      DominanceFrontier::DomSetType Set = DFI->second;
+      // Filter out stuff in Set that we do not dominate a predecessor of.
+      for (DominanceFrontier::DomSetType::iterator SetI = Set.begin(),
+             E = Set.end(); SetI != E;) {
+        bool DominatesPred = false;
+        for (pred_iterator PI = pred_begin(*SetI), E = pred_end(*SetI);
+             PI != E; ++PI)
+          if (DT.dominates(NewBB, *PI))
+            DominatesPred = true;
+        if (!DominatesPred)
+          Set.erase(SetI++);
+        else
+          ++SetI;
+      }
+      
+      addBasicBlock(NewBB, Set);
+    }
+    
+  } else {
+    // DF(NewBB) is {NewBBSucc} because NewBB does not strictly dominate
+    // NewBBSucc, but it does dominate itself (and there is an edge (NewBB ->
+    // NewBBSucc)).  NewBBSucc is the single successor of NewBB.
+    DominanceFrontier::DomSetType NewDFSet;
+    NewDFSet.insert(NewBBSucc);
+    addBasicBlock(NewBB, NewDFSet);
+  }
+  
+  // Now we must loop over all of the dominance frontiers in the function,
+  // replacing occurrences of NewBBSucc with NewBB in some cases.  All
+  // blocks that dominate a block in PredBlocks and contained NewBBSucc in
+  // their dominance frontier must be updated to contain NewBB instead.
+  //
+  for (Function::iterator FI = NewBB->getParent()->begin(),
+         FE = NewBB->getParent()->end(); FI != FE; ++FI) {
+    DominanceFrontier::iterator DFI = find(FI);
+    if (DFI == end()) continue;  // unreachable block.
+    
+    // Only consider dominators of NewBBSucc
+    if (!DFI->second.count(NewBBSucc)) continue;
+
+    bool BlockDominatesAny = false;
+    for (std::vector<BasicBlock*>::const_iterator BI = PredBlocks.begin(), 
+           BE = PredBlocks.end(); BI != BE; ++BI) {
+      if (DT.dominates(FI, *BI)) {
+        BlockDominatesAny = true;
+        break;
+      }
+    }
+    
+    if (BlockDominatesAny) {
+      // If NewBBSucc should not stay in our dominator frontier, remove it.
+      // We remove it unless there is a predecessor of NewBBSucc that we
+      // dominate, but we don't strictly dominate NewBBSucc.
+      bool ShouldRemove = true;
+      if ((BasicBlock*)FI == NewBBSucc
+          || !DT.dominates(FI, NewBBSucc)) {
+        // Okay, we know that PredDom does not strictly dominate NewBBSucc.
+        // Check to see if it dominates any predecessors of NewBBSucc.
+        for (pred_iterator PI = pred_begin(NewBBSucc),
+               E = pred_end(NewBBSucc); PI != E; ++PI)
+          if (DT.dominates(FI, *PI)) {
+            ShouldRemove = false;
+            break;
+          }
+        
+        if (ShouldRemove)
+          removeFromFrontier(DFI, NewBBSucc);
+        addToFrontier(DFI, NewBB);
+        
+        break;
+      }
+    }
+  }
+}
+
 namespace {
   class DFCalculateWorkObject {
   public:






More information about the llvm-commits mailing list