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/AnalysisDeclContext.h"
18 #include "clang/Analysis/CFG.h"
19 #include "llvm/ADT/DepthFirstIterator.h"
20 #include "llvm/ADT/GraphTraits.h"
21 #include "llvm/ADT/iterator.h"
22 #include "llvm/Support/GenericDomTree.h"
23 #include "llvm/Support/GenericDomTreeConstruction.h"
24 #include "llvm/Support/raw_ostream.h"
26 // FIXME: There is no good reason for the domtree to require a print method
27 // which accepts an LLVM Module, so remove this (and the method's argument that
28 // needs it) when that is fixed.
38 using DomTreeNode = llvm::DomTreeNodeBase<CFGBlock>;
40 /// Concrete subclass of DominatorTreeBase for Clang
41 /// This class implements the dominators tree functionality given a Clang CFG.
43 class DominatorTree : public ManagedAnalysis {
44 virtual void anchor();
47 llvm::DomTreeBase<CFGBlock> *DT;
50 DT = new llvm::DomTreeBase<CFGBlock>();
53 ~DominatorTree() override { delete DT; }
55 llvm::DomTreeBase<CFGBlock>& getBase() { return *DT; }
57 /// This method returns the root CFGBlock of the dominators tree.
58 CFGBlock *getRoot() const {
62 /// This method returns the root DomTreeNode, which is the wrapper
64 DomTreeNode *getRootNode() const {
65 return DT->getRootNode();
68 /// This method compares two dominator trees.
69 /// The method returns false if the other dominator tree matches this
70 /// dominator tree, otherwise returns true.
71 bool compare(DominatorTree &Other) const {
72 DomTreeNode *R = getRootNode();
73 DomTreeNode *OtherR = Other.getRootNode();
75 if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
78 if (DT->compare(Other.getBase()))
84 /// This method builds the dominator tree for a given CFG
85 /// The CFG information is passed via AnalysisDeclContext
86 void buildDominatorTree(AnalysisDeclContext &AC) {
88 DT->recalculate(*cfg);
91 /// This method dumps immediate dominators for each block,
92 /// mainly used for debug purposes.
94 llvm::errs() << "Immediate dominance tree (Node#,IDom#):\n";
95 for (CFG::const_iterator I = cfg->begin(),
96 E = cfg->end(); I != E; ++I) {
97 if(DT->getNode(*I)->getIDom())
98 llvm::errs() << "(" << (*I)->getBlockID()
100 << DT->getNode(*I)->getIDom()->getBlock()->getBlockID()
102 else llvm::errs() << "(" << (*I)->getBlockID()
103 << "," << (*I)->getBlockID() << ")\n";
107 /// This method tests if one CFGBlock dominates the other.
108 /// The method return true if A dominates B, false otherwise.
109 /// Note a block always dominates itself.
110 bool dominates(const CFGBlock *A, const CFGBlock *B) const {
111 return DT->dominates(A, B);
114 /// This method tests if one CFGBlock properly dominates the other.
115 /// 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 /// 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.
122 CFGBlock *findNearestCommonDominator(CFGBlock *A, CFGBlock *B) {
123 return DT->findNearestCommonDominator(A, B);
126 const CFGBlock *findNearestCommonDominator(const CFGBlock *A,
128 return DT->findNearestCommonDominator(A, B);
131 /// This method is used to update the dominator
132 /// tree information when a node's immediate dominator changes.
133 void changeImmediateDominator(CFGBlock *N, CFGBlock *NewIDom) {
134 DT->changeImmediateDominator(N, NewIDom);
137 /// This method tests if the given CFGBlock can be reachable from root.
138 /// Returns true if reachable, false otherwise.
139 bool isReachableFromEntry(const CFGBlock *A) {
140 return DT->isReachableFromEntry(A);
143 /// This method releases the memory held by the dominator tree.
144 virtual void releaseMemory() {
148 /// This method converts the dominator tree to human readable form.
149 virtual void print(raw_ostream &OS, const llvm::Module* M= nullptr) const {
159 //===-------------------------------------
160 /// DominatorTree GraphTraits specialization so the DominatorTree can be
161 /// iterable by generic graph iterators.
165 template <> struct GraphTraits< ::clang::DomTreeNode* > {
166 using NodeRef = ::clang::DomTreeNode *;
167 using ChildIteratorType = ::clang::DomTreeNode::iterator;
169 static NodeRef getEntryNode(NodeRef N) { return N; }
170 static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
171 static ChildIteratorType child_end(NodeRef N) { return N->end(); }
173 using nodes_iterator =
174 llvm::pointer_iterator<df_iterator<::clang::DomTreeNode *>>;
176 static nodes_iterator nodes_begin(::clang::DomTreeNode *N) {
177 return nodes_iterator(df_begin(getEntryNode(N)));
180 static nodes_iterator nodes_end(::clang::DomTreeNode *N) {
181 return nodes_iterator(df_end(getEntryNode(N)));
185 template <> struct GraphTraits< ::clang::DominatorTree* >
186 : public GraphTraits< ::clang::DomTreeNode* > {
187 static NodeRef getEntryNode(::clang::DominatorTree *DT) {
188 return DT->getRootNode();
191 static nodes_iterator nodes_begin(::clang::DominatorTree *N) {
192 return nodes_iterator(df_begin(getEntryNode(N)));
195 static nodes_iterator nodes_end(::clang::DominatorTree *N) {
196 return nodes_iterator(df_end(getEntryNode(N)));
202 #endif // LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H