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_ANALYSIS_ANALYSES_DOMINATORS_H
00015 #define LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
00016 
00017 #include "clang/Analysis/AnalysisContext.h"
00018 #include "clang/Analysis/CFG.h"
00019 #include "llvm/ADT/GraphTraits.h"
00020 #include "llvm/Support/GenericDomTree.h"
00021 #include "llvm/Support/GenericDomTreeConstruction.h"
00022 
00023 // FIXME: There is no good reason for the domtree to require a print method
00024 // which accepts an LLVM Module, so remove this (and the method's argument that
00025 // needs it) when that is fixed.
00026 namespace llvm {
00027 class Module;
00028 }
00029 
00030 namespace clang {
00031 
00032 class CFGBlock;
00033 typedef llvm::DomTreeNodeBase<CFGBlock> DomTreeNode;
00034 
00035 /// \brief Concrete subclass of DominatorTreeBase for Clang
00036 /// This class implements the dominators tree functionality given a Clang CFG.
00037 ///
00038 class DominatorTree : public ManagedAnalysis {
00039   virtual void anchor();
00040 public:
00041   llvm::DominatorTreeBase<CFGBlock>* DT;
00042 
00043   DominatorTree() {
00044     DT = new llvm::DominatorTreeBase<CFGBlock>(false);
00045   }
00046 
00047   ~DominatorTree() {
00048     delete DT;
00049   }
00050 
00051   llvm::DominatorTreeBase<CFGBlock>& getBase() { return *DT; }
00052 
00053   /// \brief This method returns the root CFGBlock of the dominators tree.
00054   ///
00055   inline CFGBlock *getRoot() const {
00056     return DT->getRoot();
00057   }
00058 
00059   /// \brief This method returns the root DomTreeNode, which is the wrapper
00060   /// for CFGBlock.
00061   inline DomTreeNode *getRootNode() const {
00062     return DT->getRootNode();
00063   }
00064 
00065   /// \brief This method compares two dominator trees.
00066   /// The method returns false if the other dominator tree matches this
00067   /// dominator tree, otherwise returns true.
00068   ///
00069   inline bool compare(DominatorTree &Other) const {
00070     DomTreeNode *R = getRootNode();
00071     DomTreeNode *OtherR = Other.getRootNode();
00072 
00073     if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
00074       return true;
00075 
00076     if (DT->compare(Other.getBase()))
00077       return true;
00078 
00079     return false;
00080   }
00081 
00082   /// \brief This method builds the dominator tree for a given CFG
00083   /// The CFG information is passed via AnalysisDeclContext
00084   ///
00085   void buildDominatorTree(AnalysisDeclContext &AC) {
00086     cfg = AC.getCFG();
00087     DT->recalculate(*cfg);
00088   }
00089 
00090   /// \brief This method dumps immediate dominators for each block,
00091   /// mainly used for debug purposes.
00092   ///
00093   void dump() {
00094     llvm::errs() << "Immediate dominance tree (Node#,IDom#):\n";
00095     for (CFG::const_iterator I = cfg->begin(),
00096         E = cfg->end(); I != E; ++I) {
00097       if(DT->getNode(*I)->getIDom())
00098         llvm::errs() << "(" << (*I)->getBlockID()
00099                      << ","
00100                      << DT->getNode(*I)->getIDom()->getBlock()->getBlockID()
00101                      << ")\n";
00102       else llvm::errs() << "(" << (*I)->getBlockID()
00103                         << "," << (*I)->getBlockID() << ")\n";
00104     }
00105   }
00106 
00107   /// \brief This method tests if one CFGBlock dominates the other.
00108   /// The method return true if A dominates B, false otherwise.
00109   /// Note a block always dominates itself.
00110   ///
00111   inline bool dominates(const CFGBlock* A, const CFGBlock* B) const {
00112     return DT->dominates(A, B);
00113   }
00114 
00115   /// \brief This method tests if one CFGBlock properly dominates the other.
00116   /// The method return true if A properly dominates B, false otherwise.
00117   ///
00118   bool properlyDominates(const CFGBlock*A, const CFGBlock*B) const {
00119     return DT->properlyDominates(A, B);
00120   }
00121 
00122   /// \brief This method finds the nearest common dominator CFG block
00123   /// for CFG block A and B. If there is no such block then return NULL.
00124   ///
00125   inline CFGBlock *findNearestCommonDominator(CFGBlock *A, CFGBlock *B) {
00126     return DT->findNearestCommonDominator(A, B);
00127   }
00128 
00129   inline const CFGBlock *findNearestCommonDominator(const CFGBlock *A,
00130                                                       const CFGBlock *B) {
00131     return DT->findNearestCommonDominator(A, B);
00132   }
00133 
00134   /// \brief This method is used to update the dominator
00135   /// tree information when a node's immediate dominator changes.
00136   ///
00137   inline void changeImmediateDominator(CFGBlock *N, CFGBlock *NewIDom) {
00138     DT->changeImmediateDominator(N, NewIDom);
00139   }
00140 
00141   /// \brief This method tests if the given CFGBlock can be reachable from root.
00142   /// Returns true if reachable, false otherwise.
00143   ///
00144   bool isReachableFromEntry(const CFGBlock *A) {
00145     return DT->isReachableFromEntry(A);
00146   }
00147 
00148   /// \brief This method releases the memory held by the dominator tree.
00149   ///
00150   virtual void releaseMemory() {
00151     DT->releaseMemory();
00152   }
00153 
00154   /// \brief This method converts the dominator tree to human readable form.
00155   ///
00156   virtual void print(raw_ostream &OS, const llvm::Module* M= nullptr) const {
00157     DT->print(OS);
00158   }
00159 
00160 private:
00161   CFG *cfg;
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