LLVM API Documentation

DominanceFrontier.cpp
Go to the documentation of this file.
00001 //===- DominanceFrontier.cpp - Dominance Frontier Calculation -------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "llvm/Analysis/DominanceFrontier.h"
00011 #include "llvm/ADT/SmallPtrSet.h"
00012 #include "llvm/Assembly/Writer.h"
00013 #include "llvm/Support/Debug.h"
00014 #include "llvm/Support/raw_ostream.h"
00015 using namespace llvm;
00016 
00017 char DominanceFrontier::ID = 0;
00018 INITIALIZE_PASS_BEGIN(DominanceFrontier, "domfrontier",
00019                 "Dominance Frontier Construction", true, true)
00020 INITIALIZE_PASS_DEPENDENCY(DominatorTree)
00021 INITIALIZE_PASS_END(DominanceFrontier, "domfrontier",
00022                 "Dominance Frontier Construction", true, true)
00023 
00024 namespace {
00025   class DFCalculateWorkObject {
00026   public:
00027     DFCalculateWorkObject(BasicBlock *B, BasicBlock *P, 
00028                           const DomTreeNode *N,
00029                           const DomTreeNode *PN)
00030     : currentBB(B), parentBB(P), Node(N), parentNode(PN) {}
00031     BasicBlock *currentBB;
00032     BasicBlock *parentBB;
00033     const DomTreeNode *Node;
00034     const DomTreeNode *parentNode;
00035   };
00036 }
00037 
00038 void DominanceFrontier::anchor() { }
00039 
00040 const DominanceFrontier::DomSetType &
00041 DominanceFrontier::calculate(const DominatorTree &DT,
00042                              const DomTreeNode *Node) {
00043   BasicBlock *BB = Node->getBlock();
00044   DomSetType *Result = NULL;
00045 
00046   std::vector<DFCalculateWorkObject> workList;
00047   SmallPtrSet<BasicBlock *, 32> visited;
00048 
00049   workList.push_back(DFCalculateWorkObject(BB, NULL, Node, NULL));
00050   do {
00051     DFCalculateWorkObject *currentW = &workList.back();
00052     assert (currentW && "Missing work object.");
00053 
00054     BasicBlock *currentBB = currentW->currentBB;
00055     BasicBlock *parentBB = currentW->parentBB;
00056     const DomTreeNode *currentNode = currentW->Node;
00057     const DomTreeNode *parentNode = currentW->parentNode;
00058     assert (currentBB && "Invalid work object. Missing current Basic Block");
00059     assert (currentNode && "Invalid work object. Missing current Node");
00060     DomSetType &S = Frontiers[currentBB];
00061 
00062     // Visit each block only once.
00063     if (visited.count(currentBB) == 0) {
00064       visited.insert(currentBB);
00065 
00066       // Loop over CFG successors to calculate DFlocal[currentNode]
00067       for (succ_iterator SI = succ_begin(currentBB), SE = succ_end(currentBB);
00068            SI != SE; ++SI) {
00069         // Does Node immediately dominate this successor?
00070         if (DT[*SI]->getIDom() != currentNode)
00071           S.insert(*SI);
00072       }
00073     }
00074 
00075     // At this point, S is DFlocal.  Now we union in DFup's of our children...
00076     // Loop through and visit the nodes that Node immediately dominates (Node's
00077     // children in the IDomTree)
00078     bool visitChild = false;
00079     for (DomTreeNode::const_iterator NI = currentNode->begin(), 
00080            NE = currentNode->end(); NI != NE; ++NI) {
00081       DomTreeNode *IDominee = *NI;
00082       BasicBlock *childBB = IDominee->getBlock();
00083       if (visited.count(childBB) == 0) {
00084         workList.push_back(DFCalculateWorkObject(childBB, currentBB,
00085                                                  IDominee, currentNode));
00086         visitChild = true;
00087       }
00088     }
00089 
00090     // If all children are visited or there is any child then pop this block
00091     // from the workList.
00092     if (!visitChild) {
00093 
00094       if (!parentBB) {
00095         Result = &S;
00096         break;
00097       }
00098 
00099       DomSetType::const_iterator CDFI = S.begin(), CDFE = S.end();
00100       DomSetType &parentSet = Frontiers[parentBB];
00101       for (; CDFI != CDFE; ++CDFI) {
00102         if (!DT.properlyDominates(parentNode, DT[*CDFI]))
00103           parentSet.insert(*CDFI);
00104       }
00105       workList.pop_back();
00106     }
00107 
00108   } while (!workList.empty());
00109 
00110   return *Result;
00111 }
00112 
00113 void DominanceFrontierBase::print(raw_ostream &OS, const Module* ) const {
00114   for (const_iterator I = begin(), E = end(); I != E; ++I) {
00115     OS << "  DomFrontier for BB ";
00116     if (I->first)
00117       WriteAsOperand(OS, I->first, false);
00118     else
00119       OS << " <<exit node>>";
00120     OS << " is:\t";
00121     
00122     const std::set<BasicBlock*> &BBs = I->second;
00123     
00124     for (std::set<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end();
00125          I != E; ++I) {
00126       OS << ' ';
00127       if (*I)
00128         WriteAsOperand(OS, *I, false);
00129       else
00130         OS << "<<exit node>>";
00131     }
00132     OS << "\n";
00133   }
00134 }
00135 
00136 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
00137 void DominanceFrontierBase::dump() const {
00138   print(dbgs());
00139 }
00140 #endif
00141