1 //==- Dominators.h - Implementation of dominators tree for Clang CFG C++ -*-==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the dominators tree functionality for Clang CFGs.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
15 #define LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
17 #include "clang/Analysis/AnalysisContext.h"
18 #include "clang/Analysis/CFG.h"
19 #include "llvm/ADT/GraphTraits.h"
20 #include "llvm/Support/GenericDomTree.h"
21 #include "llvm/Support/GenericDomTreeConstruction.h"
23 // FIXME: There is no good reason for the domtree to require a print method
24 // which accepts an LLVM Module, so remove this (and the method's argument that
25 // needs it) when that is fixed.
33 typedef llvm::DomTreeNodeBase<CFGBlock> DomTreeNode;
35 /// \brief Concrete subclass of DominatorTreeBase for Clang
36 /// This class implements the dominators tree functionality given a Clang CFG.
38 class DominatorTree : public ManagedAnalysis {
39 virtual void anchor();
41 llvm::DominatorTreeBase<CFGBlock>* DT;
44 DT = new llvm::DominatorTreeBase<CFGBlock>(false);
47 ~DominatorTree() override { delete DT; }
49 llvm::DominatorTreeBase<CFGBlock>& getBase() { return *DT; }
51 /// \brief This method returns the root CFGBlock of the dominators tree.
53 inline CFGBlock *getRoot() const {
57 /// \brief This method returns the root DomTreeNode, which is the wrapper
59 inline DomTreeNode *getRootNode() const {
60 return DT->getRootNode();
63 /// \brief This method compares two dominator trees.
64 /// The method returns false if the other dominator tree matches this
65 /// dominator tree, otherwise returns true.
67 inline bool compare(DominatorTree &Other) const {
68 DomTreeNode *R = getRootNode();
69 DomTreeNode *OtherR = Other.getRootNode();
71 if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
74 if (DT->compare(Other.getBase()))
80 /// \brief This method builds the dominator tree for a given CFG
81 /// The CFG information is passed via AnalysisDeclContext
83 void buildDominatorTree(AnalysisDeclContext &AC) {
85 DT->recalculate(*cfg);
88 /// \brief This method dumps immediate dominators for each block,
89 /// mainly used for debug purposes.
92 llvm::errs() << "Immediate dominance tree (Node#,IDom#):\n";
93 for (CFG::const_iterator I = cfg->begin(),
94 E = cfg->end(); I != E; ++I) {
95 if(DT->getNode(*I)->getIDom())
96 llvm::errs() << "(" << (*I)->getBlockID()
98 << DT->getNode(*I)->getIDom()->getBlock()->getBlockID()
100 else llvm::errs() << "(" << (*I)->getBlockID()
101 << "," << (*I)->getBlockID() << ")\n";
105 /// \brief This method tests if one CFGBlock dominates the other.
106 /// The method return true if A dominates B, false otherwise.
107 /// Note a block always dominates itself.
109 inline bool dominates(const CFGBlock* A, const CFGBlock* B) const {
110 return DT->dominates(A, B);
113 /// \brief This method tests if one CFGBlock properly dominates the other.
114 /// The method return true if A properly dominates B, false otherwise.
116 bool properlyDominates(const CFGBlock*A, const CFGBlock*B) const {
117 return DT->properlyDominates(A, B);
120 /// \brief This method finds the nearest common dominator CFG block
121 /// for CFG block A and B. If there is no such block then return NULL.
123 inline CFGBlock *findNearestCommonDominator(CFGBlock *A, CFGBlock *B) {
124 return DT->findNearestCommonDominator(A, B);
127 inline const CFGBlock *findNearestCommonDominator(const CFGBlock *A,
129 return DT->findNearestCommonDominator(A, B);
132 /// \brief This method is used to update the dominator
133 /// tree information when a node's immediate dominator changes.
135 inline void changeImmediateDominator(CFGBlock *N, CFGBlock *NewIDom) {
136 DT->changeImmediateDominator(N, NewIDom);
139 /// \brief This method tests if the given CFGBlock can be reachable from root.
140 /// Returns true if reachable, false otherwise.
142 bool isReachableFromEntry(const CFGBlock *A) {
143 return DT->isReachableFromEntry(A);
146 /// \brief This method releases the memory held by the dominator tree.
148 virtual void releaseMemory() {
152 /// \brief This method converts the dominator tree to human readable form.
154 virtual void print(raw_ostream &OS, const llvm::Module* M= nullptr) const {
162 } // end namespace clang
164 //===-------------------------------------
165 /// DominatorTree GraphTraits specialization so the DominatorTree can be
166 /// iterable by generic graph iterators.
169 template <> struct GraphTraits< ::clang::DomTreeNode* > {
170 typedef ::clang::DomTreeNode NodeType;
171 typedef NodeType::iterator ChildIteratorType;
173 static NodeType *getEntryNode(NodeType *N) {
176 static inline ChildIteratorType child_begin(NodeType *N) {
179 static inline ChildIteratorType child_end(NodeType *N) {
183 typedef df_iterator< ::clang::DomTreeNode* > nodes_iterator;
185 static nodes_iterator nodes_begin(::clang::DomTreeNode *N) {
186 return df_begin(getEntryNode(N));
189 static nodes_iterator nodes_end(::clang::DomTreeNode *N) {
190 return df_end(getEntryNode(N));
194 template <> struct GraphTraits< ::clang::DominatorTree* >
195 : public GraphTraits< ::clang::DomTreeNode* > {
196 static NodeType *getEntryNode(::clang::DominatorTree *DT) {
197 return DT->getRootNode();
200 static nodes_iterator nodes_begin(::clang::DominatorTree *N) {
201 return df_begin(getEntryNode(N));
204 static nodes_iterator nodes_end(::clang::DominatorTree *N) {
205 return df_end(getEntryNode(N));
208 } // end namespace llvm