00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
00140 IDom->Children.erase(I);
00141
00142
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
00154
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
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
00222 std::vector<NodeT*> Vertex;
00223
00224
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