clang API Documentation

Dominators.h
Go to the documentation of this file.
00001 //==- Dominators.h - Implementation of dominators tree for Clang CFG 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 implements the dominators tree functionality for Clang CFGs.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_DOMINATORS_H
00015 #define LLVM_CLANG_DOMINATORS_H
00016 
00017 #include "clang/Analysis/AnalysisContext.h"
00018 
00019 #include "llvm/Module.h"
00020 #include "llvm/ADT/GraphTraits.h"
00021 #include "clang/Analysis/CFG.h"
00022 #include "llvm/Analysis/Dominators.h"
00023 #include "llvm/Analysis/DominatorInternals.h"
00024 
00025 namespace clang {
00026 
00027 class CFGBlock;
00028 typedef llvm::DomTreeNodeBase<CFGBlock> DomTreeNode;
00029 
00030 /// \brief Concrete subclass of DominatorTreeBase for Clang
00031 /// This class implements the dominators tree functionality given a Clang CFG.
00032 ///
00033 class DominatorTree : public ManagedAnalysis {
00034   virtual void anchor();
00035 public:
00036   llvm::DominatorTreeBase<CFGBlock>* DT;
00037 
00038   DominatorTree() {
00039     DT = new llvm::DominatorTreeBase<CFGBlock>(false);
00040   }
00041 
00042   ~DominatorTree() {
00043     delete DT;
00044   }
00045 
00046   llvm::DominatorTreeBase<CFGBlock>& getBase() { return *DT; }
00047 
00048   /// \brief This method returns the root CFGBlock of the dominators tree.
00049   ///
00050   inline CFGBlock *getRoot() const {
00051     return DT->getRoot();
00052   }
00053 
00054   /// \brief This method returns the root DomTreeNode, which is the wrapper
00055   /// for CFGBlock.
00056   inline DomTreeNode *getRootNode() const {
00057     return DT->getRootNode();
00058   }
00059 
00060   /// \brief This method compares two dominator trees.
00061   /// The method returns false if the other dominator tree matches this
00062   /// dominator tree, otherwise returns true.
00063   ///
00064   inline bool compare(DominatorTree &Other) const {
00065     DomTreeNode *R = getRootNode();
00066     DomTreeNode *OtherR = Other.getRootNode();
00067 
00068     if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
00069       return true;
00070 
00071     if (DT->compare(Other.getBase()))
00072       return true;
00073 
00074     return false;
00075   }
00076 
00077   /// \brief This method builds the dominator tree for a given CFG
00078   /// The CFG information is passed via AnalysisDeclContext
00079   ///
00080   void buildDominatorTree(AnalysisDeclContext &AC) {
00081     cfg = AC.getCFG();
00082     DT->recalculate(*cfg);
00083   }
00084 
00085   /// \brief This method dumps immediate dominators for each block,
00086   /// mainly used for debug purposes.
00087   ///
00088   void dump() {
00089     llvm::errs() << "Immediate dominance tree (Node#,IDom#):\n";
00090     for (CFG::const_iterator I = cfg->begin(),
00091         E = cfg->end(); I != E; ++I) {
00092       if(DT->getNode(*I)->getIDom())
00093         llvm::errs() << "(" << (*I)->getBlockID()
00094                      << ","
00095                      << DT->getNode(*I)->getIDom()->getBlock()->getBlockID()
00096                      << ")\n";
00097       else llvm::errs() << "(" << (*I)->getBlockID()
00098                         << "," << (*I)->getBlockID() << ")\n";
00099     }
00100   }
00101 
00102   /// \brief This method tests if one CFGBlock dominates the other.
00103   /// The method return true if A dominates B, false otherwise.
00104   /// Note a block always dominates itself.
00105   ///
00106   inline bool dominates(const CFGBlock* A, const CFGBlock* B) const {
00107     return DT->dominates(A, B);
00108   }
00109 
00110   /// \brief This method tests if one CFGBlock properly dominates the other.
00111   /// The method return true if A properly dominates B, false otherwise.
00112   ///
00113   bool properlyDominates(const CFGBlock*A, const CFGBlock*B) const {
00114     return DT->properlyDominates(A, B);
00115   }
00116 
00117   /// \brief This method finds the nearest common dominator CFG block
00118   /// for CFG block A and B. If there is no such block then return NULL.
00119   ///
00120   inline CFGBlock *findNearestCommonDominator(CFGBlock *A, CFGBlock *B) {
00121     return DT->findNearestCommonDominator(A, B);
00122   }
00123 
00124   inline const CFGBlock *findNearestCommonDominator(const CFGBlock *A,
00125                                                       const CFGBlock *B) {
00126     return DT->findNearestCommonDominator(A, B);
00127   }
00128 
00129   /// \brief This method is used to update the dominator
00130   /// tree information when a node's immediate dominator changes.
00131   ///
00132   inline void changeImmediateDominator(CFGBlock *N, CFGBlock *NewIDom) {
00133     DT->changeImmediateDominator(N, NewIDom);
00134   }
00135 
00136   /// \brief This method tests if the given CFGBlock can be reachable from root.
00137   /// Returns true if reachable, false otherwise.
00138   ///
00139   bool isReachableFromEntry(const CFGBlock *A) {
00140     return DT->isReachableFromEntry(A);
00141   }
00142 
00143   /// \brief This method releases the memory held by the dominator tree.
00144   ///
00145   virtual void releaseMemory() {
00146     DT->releaseMemory();
00147   }
00148 
00149   /// \brief This method converts the dominator tree to human readable form.
00150   ///
00151   virtual void print(raw_ostream &OS, const llvm::Module* M= 0) const {
00152     DT->print(OS);
00153   }
00154 
00155 private:
00156   CFG *cfg;
00157 };
00158 
00159 inline void WriteAsOperand(raw_ostream &OS, const CFGBlock *BB,
00160                           bool t) {
00161   OS << "BB#" << BB->getBlockID();
00162 }
00163 
00164 } // end namespace clang
00165 
00166 //===-------------------------------------
00167 /// DominatorTree GraphTraits specialization so the DominatorTree can be
00168 /// iterable by generic graph iterators.
00169 ///
00170 namespace llvm {
00171 template <> struct GraphTraits< ::clang::DomTreeNode* > {
00172   typedef ::clang::DomTreeNode NodeType;
00173   typedef NodeType::iterator  ChildIteratorType;
00174 
00175   static NodeType *getEntryNode(NodeType *N) {
00176     return N;
00177   }
00178   static inline ChildIteratorType child_begin(NodeType *N) {
00179     return N->begin();
00180   }
00181   static inline ChildIteratorType child_end(NodeType *N) {
00182     return N->end();
00183   }
00184 
00185   typedef df_iterator< ::clang::DomTreeNode* > nodes_iterator;
00186 
00187   static nodes_iterator nodes_begin(::clang::DomTreeNode *N) {
00188     return df_begin(getEntryNode(N));
00189   }
00190 
00191   static nodes_iterator nodes_end(::clang::DomTreeNode *N) {
00192     return df_end(getEntryNode(N));
00193   }
00194 };
00195 
00196 template <> struct GraphTraits< ::clang::DominatorTree* >
00197   : public GraphTraits< ::clang::DomTreeNode* > {
00198   static NodeType *getEntryNode(::clang::DominatorTree *DT) {
00199     return DT->getRootNode();
00200   }
00201 
00202   static nodes_iterator nodes_begin(::clang::DominatorTree *N) {
00203     return df_begin(getEntryNode(N));
00204   }
00205 
00206   static nodes_iterator nodes_end(::clang::DominatorTree *N) {
00207     return df_end(getEntryNode(N));
00208   }
00209 };
00210 } // end namespace llvm
00211 
00212 #endif