LLVM API Documentation
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 file defines the DominanceFrontier class, which calculate and holds the 00011 // dominance frontier for a function. 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_DOMINANCEFRONTIER_H 00019 #define LLVM_ANALYSIS_DOMINANCEFRONTIER_H 00020 00021 #include "llvm/IR/Dominators.h" 00022 #include <map> 00023 #include <set> 00024 00025 namespace llvm { 00026 00027 //===----------------------------------------------------------------------===// 00028 /// DominanceFrontierBase - Common base class for computing forward and inverse 00029 /// dominance frontiers for a function. 00030 /// 00031 template <class BlockT> 00032 class DominanceFrontierBase { 00033 public: 00034 typedef std::set<BlockT *> DomSetType; // Dom set for a bb 00035 typedef std::map<BlockT *, DomSetType> DomSetMapType; // Dom set map 00036 00037 protected: 00038 typedef GraphTraits<BlockT *> BlockTraits; 00039 00040 DomSetMapType Frontiers; 00041 std::vector<BlockT *> Roots; 00042 const bool IsPostDominators; 00043 00044 public: 00045 DominanceFrontierBase(bool isPostDom) : IsPostDominators(isPostDom) {} 00046 00047 /// getRoots - Return the root blocks of the current CFG. This may include 00048 /// multiple blocks if we are computing post dominators. For forward 00049 /// dominators, this will always be a single block (the entry node). 00050 /// 00051 inline const std::vector<BlockT *> &getRoots() const { 00052 return Roots; 00053 } 00054 00055 BlockT *getRoot() const { 00056 assert(Roots.size() == 1 && "Should always have entry node!"); 00057 return Roots[0]; 00058 } 00059 00060 /// isPostDominator - Returns true if analysis based of postdoms 00061 /// 00062 bool isPostDominator() const { 00063 return IsPostDominators; 00064 } 00065 00066 void releaseMemory() { 00067 Frontiers.clear(); 00068 } 00069 00070 // Accessor interface: 00071 typedef typename DomSetMapType::iterator iterator; 00072 typedef typename DomSetMapType::const_iterator const_iterator; 00073 iterator begin() { return Frontiers.begin(); } 00074 const_iterator begin() const { return Frontiers.begin(); } 00075 iterator end() { return Frontiers.end(); } 00076 const_iterator end() const { return Frontiers.end(); } 00077 iterator find(BlockT *B) { return Frontiers.find(B); } 00078 const_iterator find(BlockT *B) const { return Frontiers.find(B); } 00079 00080 iterator addBasicBlock(BlockT *BB, const DomSetType &frontier) { 00081 assert(find(BB) == end() && "Block already in DominanceFrontier!"); 00082 return Frontiers.insert(std::make_pair(BB, frontier)).first; 00083 } 00084 00085 /// removeBlock - Remove basic block BB's frontier. 00086 void removeBlock(BlockT *BB); 00087 00088 void addToFrontier(iterator I, BlockT *Node); 00089 00090 void removeFromFrontier(iterator I, BlockT *Node); 00091 00092 /// compareDomSet - Return false if two domsets match. Otherwise 00093 /// return true; 00094 bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const; 00095 00096 /// compare - Return true if the other dominance frontier base matches 00097 /// this dominance frontier base. Otherwise return false. 00098 bool compare(DominanceFrontierBase<BlockT> &Other) const; 00099 00100 /// print - Convert to human readable form 00101 /// 00102 void print(raw_ostream &OS) const; 00103 00104 /// dump - Dump the dominance frontier to dbgs(). 00105 void dump() const; 00106 }; 00107 00108 //===------------------------------------- 00109 /// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is 00110 /// used to compute a forward dominator frontiers. 00111 /// 00112 template <class BlockT> 00113 class ForwardDominanceFrontierBase : public DominanceFrontierBase<BlockT> { 00114 private: 00115 typedef GraphTraits<BlockT *> BlockTraits; 00116 00117 public: 00118 typedef DominatorTreeBase<BlockT> DomTreeT; 00119 typedef DomTreeNodeBase<BlockT> DomTreeNodeT; 00120 typedef typename DominanceFrontierBase<BlockT>::DomSetType DomSetType; 00121 00122 ForwardDominanceFrontierBase() : DominanceFrontierBase<BlockT>(false) {} 00123 00124 void analyze(DomTreeT &DT) { 00125 this->Roots = DT.getRoots(); 00126 assert(this->Roots.size() == 1 && 00127 "Only one entry block for forward domfronts!"); 00128 calculate(DT, DT[this->Roots[0]]); 00129 } 00130 00131 const DomSetType &calculate(const DomTreeT &DT, const DomTreeNodeT *Node); 00132 }; 00133 00134 class DominanceFrontier : public FunctionPass { 00135 ForwardDominanceFrontierBase<BasicBlock> Base; 00136 00137 public: 00138 typedef DominatorTreeBase<BasicBlock> DomTreeT; 00139 typedef DomTreeNodeBase<BasicBlock> DomTreeNodeT; 00140 typedef DominanceFrontierBase<BasicBlock>::DomSetType DomSetType; 00141 typedef DominanceFrontierBase<BasicBlock>::iterator iterator; 00142 typedef DominanceFrontierBase<BasicBlock>::const_iterator const_iterator; 00143 00144 static char ID; // Pass ID, replacement for typeid 00145 00146 DominanceFrontier(); 00147 00148 ForwardDominanceFrontierBase<BasicBlock> &getBase() { return Base; } 00149 00150 inline const std::vector<BasicBlock *> &getRoots() const { 00151 return Base.getRoots(); 00152 } 00153 00154 BasicBlock *getRoot() const { return Base.getRoot(); } 00155 00156 bool isPostDominator() const { return Base.isPostDominator(); } 00157 00158 iterator begin() { return Base.begin(); } 00159 00160 const_iterator begin() const { return Base.begin(); } 00161 00162 iterator end() { return Base.end(); } 00163 00164 const_iterator end() const { return Base.end(); } 00165 00166 iterator find(BasicBlock *B) { return Base.find(B); } 00167 00168 const_iterator find(BasicBlock *B) const { return Base.find(B); } 00169 00170 iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) { 00171 return Base.addBasicBlock(BB, frontier); 00172 } 00173 00174 void removeBlock(BasicBlock *BB) { return Base.removeBlock(BB); } 00175 00176 void addToFrontier(iterator I, BasicBlock *Node) { 00177 return Base.addToFrontier(I, Node); 00178 } 00179 00180 void removeFromFrontier(iterator I, BasicBlock *Node) { 00181 return Base.removeFromFrontier(I, Node); 00182 } 00183 00184 bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const { 00185 return Base.compareDomSet(DS1, DS2); 00186 } 00187 00188 bool compare(DominanceFrontierBase<BasicBlock> &Other) const { 00189 return Base.compare(Other); 00190 } 00191 00192 void releaseMemory() override; 00193 00194 bool runOnFunction(Function &) override; 00195 00196 void getAnalysisUsage(AnalysisUsage &AU) const override; 00197 00198 void print(raw_ostream &OS, const Module * = nullptr) const override; 00199 00200 void dump() const; 00201 }; 00202 00203 EXTERN_TEMPLATE_INSTANTIATION(class DominanceFrontierBase<BasicBlock>); 00204 EXTERN_TEMPLATE_INSTANTIATION(class ForwardDominanceFrontierBase<BasicBlock>); 00205 00206 } // End llvm namespace 00207 00208 #endif