• Main Page
  • Classes
  • Files
  • File List

Dominators.h

00001 //===- llvm/Analysis/Dominators.h - Dominator Info Calculation --*- 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 file defines the following classes:
00011 //  1. DominatorTree: Represent dominators as an explicit tree structure.
00012 //  2. DominanceFrontier: Calculate and hold the dominance frontier for a
00013 //     function.
00014 //
00015 //  These data structures are listed in increasing order of complexity.  It
00016 //  takes longer to calculate the dominator frontier, for example, than the
00017 //  DominatorTree mapping.
00018 //
00019 //===----------------------------------------------------------------------===//
00020 
00021 #ifndef LLVM_ANALYSIS_DOMINATORS_H
00022 #define LLVM_ANALYSIS_DOMINATORS_H
00023 
00024 #include "llvm/Pass.h"
00025 #include "llvm/Function.h"
00026 #include "llvm/Instructions.h"
00027 #include "llvm/ADT/DenseMap.h"
00028 #include "llvm/ADT/DepthFirstIterator.h"
00029 #include "llvm/ADT/GraphTraits.h"
00030 #include "llvm/ADT/SmallPtrSet.h"
00031 #include "llvm/ADT/SmallVector.h"
00032 #include "llvm/Assembly/Writer.h"
00033 #include "llvm/Support/CFG.h"
00034 #include "llvm/Support/Compiler.h"
00035 #include "llvm/Support/raw_ostream.h"
00036 #include <algorithm>
00037 #include <map>
00038 #include <set>
00039 
00040 namespace llvm {
00041 
00042 //===----------------------------------------------------------------------===//
00046 template <class NodeT>
00047 class DominatorBase {
00048 protected:
00049   std::vector<NodeT*> Roots;
00050   const bool IsPostDominators;
00051   inline explicit DominatorBase(bool isPostDom) :
00052     Roots(), IsPostDominators(isPostDom) {}
00053 public:
00054 
00059   inline const std::vector<NodeT*> &getRoots() const { return Roots; }
00060 
00063   bool isPostDominator() const { return IsPostDominators; }
00064 };
00065 
00066 
00067 //===----------------------------------------------------------------------===//
00068 // DomTreeNode - Dominator Tree Node
00069 template<class NodeT> class DominatorTreeBase;
00070 struct PostDominatorTree;
00071 class MachineBasicBlock;
00072 
00073 template <class NodeT>
00074 class DomTreeNodeBase {
00075   NodeT *TheBB;
00076   DomTreeNodeBase<NodeT> *IDom;
00077   std::vector<DomTreeNodeBase<NodeT> *> Children;
00078   int DFSNumIn, DFSNumOut;
00079 
00080   template<class N> friend class DominatorTreeBase;
00081   friend struct PostDominatorTree;
00082 public:
00083   typedef typename std::vector<DomTreeNodeBase<NodeT> *>::iterator iterator;
00084   typedef typename std::vector<DomTreeNodeBase<NodeT> *>::const_iterator
00085                    const_iterator;
00086 
00087   iterator begin()             { return Children.begin(); }
00088   iterator end()               { return Children.end(); }
00089   const_iterator begin() const { return Children.begin(); }
00090   const_iterator end()   const { return Children.end(); }
00091 
00092   NodeT *getBlock() const { return TheBB; }
00093   DomTreeNodeBase<NodeT> *getIDom() const { return IDom; }
00094   const std::vector<DomTreeNodeBase<NodeT>*> &getChildren() const {
00095     return Children;
00096   }
00097 
00098   DomTreeNodeBase(NodeT *BB, DomTreeNodeBase<NodeT> *iDom)
00099     : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) { }
00100 
00101   DomTreeNodeBase<NodeT> *addChild(DomTreeNodeBase<NodeT> *C) {
00102     Children.push_back(C);
00103     return C;
00104   }
00105 
00106   size_t getNumChildren() const {
00107     return Children.size();
00108   }
00109 
00110   void clearAllChildren() {
00111     Children.clear();
00112   }
00113 
00114   bool compare(DomTreeNodeBase<NodeT> *Other) {
00115     if (getNumChildren() != Other->getNumChildren())
00116       return true;
00117 
00118     SmallPtrSet<NodeT *, 4> OtherChildren;
00119     for(iterator I = Other->begin(), E = Other->end(); I != E; ++I) {
00120       NodeT *Nd = (*I)->getBlock();
00121       OtherChildren.insert(Nd);
00122     }
00123 
00124     for(iterator I = begin(), E = end(); I != E; ++I) {
00125       NodeT *N = (*I)->getBlock();
00126       if (OtherChildren.count(N) == 0)
00127         return true;
00128     }
00129     return false;
00130   }
00131 
00132   void setIDom(DomTreeNodeBase<NodeT> *NewIDom) {
00133     assert(IDom && "No immediate dominator?");
00134     if (IDom != NewIDom) {
00135       typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I =
00136                   std::find(IDom->Children.begin(), IDom->Children.end(), this);
00137       assert(I != IDom->Children.end() &&
00138              "Not in immediate dominator children set!");
00139       // I am no longer your child...
00140       IDom->Children.erase(I);
00141 
00142       // Switch to new dominator
00143       IDom = NewIDom;
00144       IDom->Children.push_back(this);
00145     }
00146   }
00147 
00150   unsigned getDFSNumIn() const { return DFSNumIn; }
00151   unsigned getDFSNumOut() const { return DFSNumOut; }
00152 private:
00153   // Return true if this node is dominated by other. Use this only if DFS info
00154   // is valid.
00155   bool DominatedBy(const DomTreeNodeBase<NodeT> *other) const {
00156     return this->DFSNumIn >= other->DFSNumIn &&
00157       this->DFSNumOut <= other->DFSNumOut;
00158   }
00159 };
00160 
00161 EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<BasicBlock>);
00162 EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<MachineBasicBlock>);
00163 
00164 template<class NodeT>
00165 static raw_ostream &operator<<(raw_ostream &o,
00166                                const DomTreeNodeBase<NodeT> *Node) {
00167   if (Node->getBlock())
00168     WriteAsOperand(o, Node->getBlock(), false);
00169   else
00170     o << " <<exit node>>";
00171 
00172   o << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}";
00173 
00174   return o << "\n";
00175 }
00176 
00177 template<class NodeT>
00178 static void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o,
00179                          unsigned Lev) {
00180   o.indent(2*Lev) << "[" << Lev << "] " << N;
00181   for (typename DomTreeNodeBase<NodeT>::const_iterator I = N->begin(),
00182        E = N->end(); I != E; ++I)
00183     PrintDomTree<NodeT>(*I, o, Lev+1);
00184 }
00185 
00186 typedef DomTreeNodeBase<BasicBlock> DomTreeNode;
00187 
00188 //===----------------------------------------------------------------------===//
00191 
00192 template<class FuncT, class N>
00193 void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT,
00194                FuncT& F);
00195 
00196 template<class NodeT>
00197 class DominatorTreeBase : public DominatorBase<NodeT> {
00198 protected:
00199   typedef DenseMap<NodeT*, DomTreeNodeBase<NodeT>*> DomTreeNodeMapType;
00200   DomTreeNodeMapType DomTreeNodes;
00201   DomTreeNodeBase<NodeT> *RootNode;
00202 
00203   bool DFSInfoValid;
00204   unsigned int SlowQueries;
00205   // Information record used during immediate dominators computation.
00206   struct InfoRec {
00207     unsigned DFSNum;
00208     unsigned Semi;
00209     unsigned Size;
00210     NodeT *Label, *Child;
00211     unsigned Parent, Ancestor;
00212 
00213     std::vector<NodeT*> Bucket;
00214 
00215     InfoRec() : DFSNum(0), Semi(0), Size(0), Label(0), Child(0), Parent(0),
00216                 Ancestor(0) {}
00217   };
00218 
00219   DenseMap<NodeT*, NodeT*> IDoms;
00220 
00221   // Vertex - Map the DFS number to the BasicBlock*
00222   std::vector<NodeT*> Vertex;
00223 
00224   // Info - Collection of information used during the computation of idoms.
00225   DenseMap<NodeT*, InfoRec> Info;
00226 
00227   void reset() {
00228     for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(),
00229            E = DomTreeNodes.end(); I != E; ++I)
00230       delete I->second;
00231     DomTreeNodes.clear();
00232     IDoms.clear();
00233     this->Roots.clear();
00234     Vertex.clear();
00235     RootNode = 0;
00236   }
00237 
00238   // NewBB is split and now it