LLVM API Documentation

DominanceFrontierImpl.h
Go to the documentation of this file.
00001 //===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===//
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 // This is the generic implementation of the DominanceFrontier class, which
00011 // calculate and holds the dominance frontier for a function for.
00012 //
00013 // This should be considered deprecated, don't add any more uses of this data
00014 // structure.
00015 //
00016 //===----------------------------------------------------------------------===//
00017 
00018 #ifndef LLVM_ANALYSIS_DOMINANCEFRONTIERIMPL_H
00019 #define LLVM_ANALYSIS_DOMINANCEFRONTIERIMPL_H
00020 
00021 #include "llvm/ADT/SmallPtrSet.h"
00022 #include "llvm/Support/Debug.h"
00023 
00024 namespace llvm {
00025 
00026 namespace {
00027 template <class BlockT>
00028 class DFCalculateWorkObject {
00029 public:
00030   typedef DomTreeNodeBase<BlockT> DomTreeNodeT;
00031 
00032   DFCalculateWorkObject(BlockT *B, BlockT *P, const DomTreeNodeT *N,
00033                         const DomTreeNodeT *PN)
00034       : currentBB(B), parentBB(P), Node(N), parentNode(PN) {}
00035   BlockT *currentBB;
00036   BlockT *parentBB;
00037   const DomTreeNodeT *Node;
00038   const DomTreeNodeT *parentNode;
00039 };
00040 }
00041 
00042 template <class BlockT>
00043 void DominanceFrontierBase<BlockT>::removeBlock(BlockT *BB) {
00044   assert(find(BB) != end() && "Block is not in DominanceFrontier!");
00045   for (iterator I = begin(), E = end(); I != E; ++I)
00046     I->second.erase(BB);
00047   Frontiers.erase(BB);
00048 }
00049 
00050 template <class BlockT>
00051 void DominanceFrontierBase<BlockT>::addToFrontier(iterator I,
00052                                                   BlockT *Node) {
00053   assert(I != end() && "BB is not in DominanceFrontier!");
00054   assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
00055   I->second.erase(Node);
00056 }
00057 
00058 template <class BlockT>
00059 void DominanceFrontierBase<BlockT>::removeFromFrontier(iterator I,
00060                                                        BlockT *Node) {
00061   assert(I != end() && "BB is not in DominanceFrontier!");
00062   assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
00063   I->second.erase(Node);
00064 }
00065 
00066 template <class BlockT>
00067 bool DominanceFrontierBase<BlockT>::compareDomSet(DomSetType &DS1,
00068                                                   const DomSetType &DS2) const {
00069   std::set<BlockT *> tmpSet;
00070   for (BlockT *BB : DS2)
00071     tmpSet.insert(BB);
00072 
00073   for (typename DomSetType::const_iterator I = DS1.begin(), E = DS1.end();
00074        I != E;) {
00075     BlockT *Node = *I++;
00076 
00077     if (tmpSet.erase(Node) == 0)
00078       // Node is in DS1 but tnot in DS2.
00079       return true;
00080   }
00081 
00082   if (!tmpSet.empty()) {
00083     // There are nodes that are in DS2 but not in DS1.
00084     return true;
00085   }
00086 
00087   // DS1 and DS2 matches.
00088   return false;
00089 }
00090 
00091 template <class BlockT>
00092 bool DominanceFrontierBase<BlockT>::compare(
00093     DominanceFrontierBase<BlockT> &Other) const {
00094   DomSetMapType tmpFrontiers;
00095   for (typename DomSetMapType::const_iterator I = Other.begin(),
00096                                               E = Other.end();
00097        I != E; ++I)
00098     tmpFrontiers.insert(std::make_pair(I->first, I->second));
00099 
00100   for (typename DomSetMapType::iterator I = tmpFrontiers.begin(),
00101                                         E = tmpFrontiers.end();
00102        I != E;) {
00103     BlockT *Node = I->first;
00104     const_iterator DFI = find(Node);
00105     if (DFI == end())
00106       return true;
00107 
00108     if (compareDomSet(I->second, DFI->second))
00109       return true;
00110 
00111     ++I;
00112     tmpFrontiers.erase(Node);
00113   }
00114 
00115   if (!tmpFrontiers.empty())
00116     return true;
00117 
00118   return false;
00119 }
00120 
00121 template <class BlockT>
00122 void DominanceFrontierBase<BlockT>::print(raw_ostream &OS) const {
00123   for (const_iterator I = begin(), E = end(); I != E; ++I) {
00124     OS << "  DomFrontier for BB ";
00125     if (I->first)
00126       I->first->printAsOperand(OS, false);
00127     else
00128       OS << " <<exit node>>";
00129     OS << " is:\t";
00130 
00131     const std::set<BlockT *> &BBs = I->second;
00132 
00133     for (const BlockT *BB : BBs) {
00134       OS << ' ';
00135       if (BB)
00136         BB->printAsOperand(OS, false);
00137       else
00138         OS << "<<exit node>>";
00139     }
00140     OS << '\n';
00141   }
00142 }
00143 
00144 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
00145 template <class BlockT>
00146 void DominanceFrontierBase<BlockT>::dump() const {
00147   print(dbgs());
00148 }
00149 #endif
00150 
00151 template <class BlockT>
00152 const typename ForwardDominanceFrontierBase<BlockT>::DomSetType &
00153 ForwardDominanceFrontierBase<BlockT>::calculate(const DomTreeT &DT,
00154                                                 const DomTreeNodeT *Node) {
00155   BlockT *BB = Node->getBlock();
00156   DomSetType *Result = nullptr;
00157 
00158   std::vector<DFCalculateWorkObject<BlockT>> workList;
00159   SmallPtrSet<BlockT *, 32> visited;
00160 
00161   workList.push_back(DFCalculateWorkObject<BlockT>(BB, nullptr, Node, nullptr));
00162   do {
00163     DFCalculateWorkObject<BlockT> *currentW = &workList.back();
00164     assert(currentW && "Missing work object.");
00165 
00166     BlockT *currentBB = currentW->currentBB;
00167     BlockT *parentBB = currentW->parentBB;
00168     const DomTreeNodeT *currentNode = currentW->Node;
00169     const DomTreeNodeT *parentNode = currentW->parentNode;
00170     assert(currentBB && "Invalid work object. Missing current Basic Block");
00171     assert(currentNode && "Invalid work object. Missing current Node");
00172     DomSetType &S = this->Frontiers[currentBB];
00173 
00174     // Visit each block only once.
00175     if (visited.count(currentBB) == 0) {
00176       visited.insert(currentBB);
00177 
00178       // Loop over CFG successors to calculate DFlocal[currentNode]
00179       for (auto SI = BlockTraits::child_begin(currentBB),
00180                 SE = BlockTraits::child_end(currentBB);
00181            SI != SE; ++SI) {
00182         // Does Node immediately dominate this successor?
00183         if (DT[*SI]->getIDom() != currentNode)
00184           S.insert(*SI);
00185       }
00186     }
00187 
00188     // At this point, S is DFlocal.  Now we union in DFup's of our children...
00189     // Loop through and visit the nodes that Node immediately dominates (Node's
00190     // children in the IDomTree)
00191     bool visitChild = false;
00192     for (typename DomTreeNodeT::const_iterator NI = currentNode->begin(),
00193                                                NE = currentNode->end();
00194          NI != NE; ++NI) {
00195       DomTreeNodeT *IDominee = *NI;
00196       BlockT *childBB = IDominee->getBlock();
00197       if (visited.count(childBB) == 0) {
00198         workList.push_back(DFCalculateWorkObject<BlockT>(
00199             childBB, currentBB, IDominee, currentNode));
00200         visitChild = true;
00201       }
00202     }
00203 
00204     // If all children are visited or there is any child then pop this block
00205     // from the workList.
00206     if (!visitChild) {
00207       if (!parentBB) {
00208         Result = &S;
00209         break;
00210       }
00211 
00212       typename DomSetType::const_iterator CDFI = S.begin(), CDFE = S.end();
00213       DomSetType &parentSet = this->Frontiers[parentBB];
00214       for (; CDFI != CDFE; ++CDFI) {
00215         if (!DT.properlyDominates(parentNode, DT[*CDFI]))
00216           parentSet.insert(*CDFI);
00217       }
00218       workList.pop_back();
00219     }
00220 
00221   } while (!workList.empty());
00222 
00223   return *Result;
00224 }
00225 
00226 } // End llvm namespace
00227 
00228 #endif