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/Analysis/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 class DominanceFrontierBase : public FunctionPass { 00032 public: 00033 typedef std::set<BasicBlock*> DomSetType; // Dom set for a bb 00034 typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map 00035 protected: 00036 DomSetMapType Frontiers; 00037 std::vector<BasicBlock*> Roots; 00038 const bool IsPostDominators; 00039 00040 public: 00041 DominanceFrontierBase(char &ID, bool isPostDom) 00042 : FunctionPass(ID), IsPostDominators(isPostDom) {} 00043 00044 /// getRoots - Return the root blocks of the current CFG. This may include 00045 /// multiple blocks if we are computing post dominators. For forward 00046 /// dominators, this will always be a single block (the entry node). 00047 /// 00048 inline const std::vector<BasicBlock*> &getRoots() const { return Roots; } 00049 00050 /// isPostDominator - Returns true if analysis based of postdoms 00051 /// 00052 bool isPostDominator() const { return IsPostDominators; } 00053 00054 virtual void releaseMemory() { Frontiers.clear(); } 00055 00056 // Accessor interface: 00057 typedef DomSetMapType::iterator iterator; 00058 typedef DomSetMapType::const_iterator const_iterator; 00059 iterator begin() { return Frontiers.begin(); } 00060 const_iterator begin() const { return Frontiers.begin(); } 00061 iterator end() { return Frontiers.end(); } 00062 const_iterator end() const { return Frontiers.end(); } 00063 iterator find(BasicBlock *B) { return Frontiers.find(B); } 00064 const_iterator find(BasicBlock *B) const { return Frontiers.find(B); } 00065 00066 iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) { 00067 assert(find(BB) == end() && "Block already in DominanceFrontier!"); 00068 return Frontiers.insert(std::make_pair(BB, frontier)).first; 00069 } 00070 00071 /// removeBlock - Remove basic block BB's frontier. 00072 void removeBlock(BasicBlock *BB) { 00073 assert(find(BB) != end() && "Block is not in DominanceFrontier!"); 00074 for (iterator I = begin(), E = end(); I != E; ++I) 00075 I->second.erase(BB); 00076 Frontiers.erase(BB); 00077 } 00078 00079 void addToFrontier(iterator I, BasicBlock *Node) { 00080 assert(I != end() && "BB is not in DominanceFrontier!"); 00081 I->second.insert(Node); 00082 } 00083 00084 void removeFromFrontier(iterator I, BasicBlock *Node) { 00085 assert(I != end() && "BB is not in DominanceFrontier!"); 00086 assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB"); 00087 I->second.erase(Node); 00088 } 00089 00090 /// compareDomSet - Return false if two domsets match. Otherwise 00091 /// return true; 00092 bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const { 00093 std::set<BasicBlock *> tmpSet; 00094 for (DomSetType::const_iterator I = DS2.begin(), 00095 E = DS2.end(); I != E; ++I) 00096 tmpSet.insert(*I); 00097 00098 for (DomSetType::const_iterator I = DS1.begin(), 00099 E = DS1.end(); I != E; ) { 00100 BasicBlock *Node = *I++; 00101 00102 if (tmpSet.erase(Node) == 0) 00103 // Node is in DS1 but not in DS2. 00104 return true; 00105 } 00106 00107 if (!tmpSet.empty()) 00108 // There are nodes that are in DS2 but not in DS1. 00109 return true; 00110 00111 // DS1 and DS2 matches. 00112 return false; 00113 } 00114 00115 /// compare - Return true if the other dominance frontier base matches 00116 /// this dominance frontier base. Otherwise return false. 00117 bool compare(DominanceFrontierBase &Other) const { 00118 DomSetMapType tmpFrontiers; 00119 for (DomSetMapType::const_iterator I = Other.begin(), 00120 E = Other.end(); I != E; ++I) 00121 tmpFrontiers.insert(std::make_pair(I->first, I->second)); 00122 00123 for (DomSetMapType::iterator I = tmpFrontiers.begin(), 00124 E = tmpFrontiers.end(); I != E; ) { 00125 BasicBlock *Node = I->first; 00126 const_iterator DFI = find(Node); 00127 if (DFI == end()) 00128 return true; 00129 00130 if (compareDomSet(I->second, DFI->second)) 00131 return true; 00132 00133 ++I; 00134 tmpFrontiers.erase(Node); 00135 } 00136 00137 if (!tmpFrontiers.empty()) 00138 return true; 00139 00140 return false; 00141 } 00142 00143 /// print - Convert to human readable form 00144 /// 00145 virtual void print(raw_ostream &OS, const Module* = 0) const; 00146 00147 /// dump - Dump the dominance frontier to dbgs(). 00148 void dump() const; 00149 }; 00150 00151 00152 //===------------------------------------- 00153 /// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is 00154 /// used to compute a forward dominator frontiers. 00155 /// 00156 class DominanceFrontier : public DominanceFrontierBase { 00157 virtual void anchor(); 00158 public: 00159 static char ID; // Pass ID, replacement for typeid 00160 DominanceFrontier() : 00161 DominanceFrontierBase(ID, false) { 00162 initializeDominanceFrontierPass(*PassRegistry::getPassRegistry()); 00163 } 00164 00165 BasicBlock *getRoot() const { 00166 assert(Roots.size() == 1 && "Should always have entry node!"); 00167 return Roots[0]; 00168 } 00169 00170 virtual bool runOnFunction(Function &) { 00171 Frontiers.clear(); 00172 DominatorTree &DT = getAnalysis<DominatorTree>(); 00173 Roots = DT.getRoots(); 00174 assert(Roots.size() == 1 && "Only one entry block for forward domfronts!"); 00175 calculate(DT, DT[Roots[0]]); 00176 return false; 00177 } 00178 00179 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 00180 AU.setPreservesAll(); 00181 AU.addRequired<DominatorTree>(); 00182 } 00183 00184 const DomSetType &calculate(const DominatorTree &DT, 00185 const DomTreeNode *Node); 00186 }; 00187 00188 } // End llvm namespace 00189 00190 #endif