13#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
14#define LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
18#include "llvm/ADT/DepthFirstIterator.h"
19#include "llvm/ADT/GraphTraits.h"
20#include "llvm/ADT/iterator.h"
21#include "llvm/Support/GenericIteratedDominanceFrontier.h"
22#include "llvm/Support/GenericDomTree.h"
23#include "llvm/Support/GenericDomTreeConstruction.h"
24#include "llvm/Support/raw_ostream.h"
41template <
bool IsPostDom>
43 virtual void anchor();
67 return DT.getRootNode();
77 if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
80 if (DT.compare(
Other.getBase()))
95 llvm::errs() <<
"Immediate " << (IsPostDom ?
"post " :
"")
96 <<
"dominance tree (Node#,IDom#):\n";
98 E = cfg->
end(); I !=
E; ++I) {
101 "LLVM's Dominator tree builder uses nullpointers to signify the "
105 if (IDom && IDom->getBlock())
106 llvm::errs() <<
"(" << (*I)->getBlockID()
108 << IDom->getBlock()->getBlockID()
111 bool IsEntryBlock = *I == &(*I)->getParent()->getEntry();
112 bool IsExitBlock = *I == &(*I)->getParent()->getExit();
114 bool IsDomTreeRoot = !IDom && !IsPostDom && IsEntryBlock;
115 bool IsPostDomTreeRoot =
116 IDom && !IDom->getBlock() && IsPostDom && IsExitBlock;
118 assert((IsDomTreeRoot || IsPostDomTreeRoot) &&
119 "If the immediate dominator node is nullptr, the CFG block "
120 "should be the exit point (since it's the root of the dominator "
121 "tree), or if the CFG block it refers to is a nullpointer, it "
122 "must be the entry block (since it's the root of the post "
126 (void)IsPostDomTreeRoot;
128 llvm::errs() <<
"(" << (*I)->getBlockID()
129 <<
"," << (*I)->getBlockID() <<
")\n";
137 return DT.dominates(A, B);
144 return DT.properlyDominates(A, B);
150 return DT.findNearestCommonDominator(A, B);
155 return DT.findNearestCommonDominator(A, B);
161 DT.changeImmediateDominator(N, NewIDom);
166 return DT.isReachableFromEntry(A);
173 virtual void print(raw_ostream &OS,
const llvm::Module* M=
nullptr)
const {
191namespace IDFCalculatorDetail {
194template <
bool IsPostDom>
195struct ChildrenGetterTy<
clang::CFGBlock, IsPostDom> {
196 using NodeRef =
typename GraphTraits<clang::CFGBlock *>::NodeRef;
200 using OrderedNodeTy =
201 typename IDFCalculatorBase<clang::CFGBlock, IsPostDom>::OrderedNodeTy;
203 auto Children = children<OrderedNodeTy>(N);
204 ChildrenTy Ret{Children.begin(), Children.end()};
205 llvm::erase(Ret,
nullptr);
216 using IDFCalculator = llvm::IDFCalculatorBase<
CFGBlock,
true>;
221 IDFCalculator IDFCalc;
223 llvm::DenseMap<CFGBlock *, CFGBlockVector> ControlDepenencyMap;
227 : PostDomTree(cfg), IDFCalc(PostDomTree.getBase()) {}
233 auto It = ControlDepenencyMap.find(A);
234 if (It == ControlDepenencyMap.end()) {
236 IDFCalc.setDefiningBlocks(DefiningBlock);
239 IDFCalc.calculate(ControlDependencies);
241 It = ControlDepenencyMap.insert({A, ControlDependencies}).first;
244 assert(It != ControlDepenencyMap.end());
256 llvm::errs() <<
"Control dependencies (Node#,Dependency#):\n";
260 "LLVM's Dominator tree builder uses nullpointers to signify the "
264 llvm::errs() <<
"(" << BB->getBlockID()
266 << isControlDependency->getBlockID()
280template <>
struct GraphTraits<
clang::DomTreeNode *> {
289 llvm::pointer_iterator<df_iterator<::clang::DomTreeNode *>>;