1 //===- Dominators.h - Dominator Info Calculation ----------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file defines the DominatorTree class, which provides fast and efficient
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_IR_DOMINATORS_H
15 #define LLVM_IR_DOMINATORS_H
17 #include "llvm/ADT/DenseMapInfo.h"
18 #include "llvm/ADT/DepthFirstIterator.h"
19 #include "llvm/ADT/GraphTraits.h"
20 #include "llvm/ADT/Hashing.h"
21 #include "llvm/IR/BasicBlock.h"
22 #include "llvm/IR/CFG.h"
23 #include "llvm/IR/PassManager.h"
24 #include "llvm/Pass.h"
25 #include "llvm/Support/GenericDomTree.h"
35 extern template class DomTreeNodeBase
<BasicBlock
>;
36 extern template class DominatorTreeBase
<BasicBlock
, false>; // DomTree
37 extern template class DominatorTreeBase
<BasicBlock
, true>; // PostDomTree
39 extern template class cfg::Update
<BasicBlock
*>;
41 namespace DomTreeBuilder
{
42 using BBDomTree
= DomTreeBase
<BasicBlock
>;
43 using BBPostDomTree
= PostDomTreeBase
<BasicBlock
>;
45 using BBUpdates
= ArrayRef
<llvm::cfg::Update
<BasicBlock
*>>;
47 extern template void Calculate
<BBDomTree
>(BBDomTree
&DT
);
48 extern template void CalculateWithUpdates
<BBDomTree
>(BBDomTree
&DT
,
51 extern template void Calculate
<BBPostDomTree
>(BBPostDomTree
&DT
);
53 extern template void InsertEdge
<BBDomTree
>(BBDomTree
&DT
, BasicBlock
*From
,
55 extern template void InsertEdge
<BBPostDomTree
>(BBPostDomTree
&DT
,
59 extern template void DeleteEdge
<BBDomTree
>(BBDomTree
&DT
, BasicBlock
*From
,
61 extern template void DeleteEdge
<BBPostDomTree
>(BBPostDomTree
&DT
,
65 extern template void ApplyUpdates
<BBDomTree
>(BBDomTree
&DT
, BBUpdates
);
66 extern template void ApplyUpdates
<BBPostDomTree
>(BBPostDomTree
&DT
, BBUpdates
);
68 extern template bool Verify
<BBDomTree
>(const BBDomTree
&DT
,
69 BBDomTree::VerificationLevel VL
);
70 extern template bool Verify
<BBPostDomTree
>(const BBPostDomTree
&DT
,
71 BBPostDomTree::VerificationLevel VL
);
72 } // namespace DomTreeBuilder
74 using DomTreeNode
= DomTreeNodeBase
<BasicBlock
>;
76 class BasicBlockEdge
{
77 const BasicBlock
*Start
;
78 const BasicBlock
*End
;
81 BasicBlockEdge(const BasicBlock
*Start_
, const BasicBlock
*End_
) :
82 Start(Start_
), End(End_
) {}
84 BasicBlockEdge(const std::pair
<BasicBlock
*, BasicBlock
*> &Pair
)
85 : Start(Pair
.first
), End(Pair
.second
) {}
87 BasicBlockEdge(const std::pair
<const BasicBlock
*, const BasicBlock
*> &Pair
)
88 : Start(Pair
.first
), End(Pair
.second
) {}
90 const BasicBlock
*getStart() const {
94 const BasicBlock
*getEnd() const {
98 /// Check if this is the only edge between Start and End.
99 bool isSingleEdge() const;
102 template <> struct DenseMapInfo
<BasicBlockEdge
> {
103 using BBInfo
= DenseMapInfo
<const BasicBlock
*>;
105 static unsigned getHashValue(const BasicBlockEdge
*V
);
107 static inline BasicBlockEdge
getEmptyKey() {
108 return BasicBlockEdge(BBInfo::getEmptyKey(), BBInfo::getEmptyKey());
111 static inline BasicBlockEdge
getTombstoneKey() {
112 return BasicBlockEdge(BBInfo::getTombstoneKey(), BBInfo::getTombstoneKey());
115 static unsigned getHashValue(const BasicBlockEdge
&Edge
) {
116 return hash_combine(BBInfo::getHashValue(Edge
.getStart()),
117 BBInfo::getHashValue(Edge
.getEnd()));
120 static bool isEqual(const BasicBlockEdge
&LHS
, const BasicBlockEdge
&RHS
) {
121 return BBInfo::isEqual(LHS
.getStart(), RHS
.getStart()) &&
122 BBInfo::isEqual(LHS
.getEnd(), RHS
.getEnd());
126 /// Concrete subclass of DominatorTreeBase that is used to compute a
127 /// normal dominator tree.
129 /// Definition: A block is said to be forward statically reachable if there is
130 /// a path from the entry of the function to the block. A statically reachable
131 /// block may become statically unreachable during optimization.
133 /// A forward unreachable block may appear in the dominator tree, or it may
134 /// not. If it does, dominance queries will return results as if all reachable
135 /// blocks dominate it. When asking for a Node corresponding to a potentially
136 /// unreachable block, calling code must handle the case where the block was
137 /// unreachable and the result of getNode() is nullptr.
139 /// Generally, a block known to be unreachable when the dominator tree is
140 /// constructed will not be in the tree. One which becomes unreachable after
141 /// the dominator tree is initially constructed may still exist in the tree,
142 /// even if the tree is properly updated. Calling code should not rely on the
143 /// preceding statements; this is stated only to assist human understanding.
144 class DominatorTree
: public DominatorTreeBase
<BasicBlock
, false> {
146 using Base
= DominatorTreeBase
<BasicBlock
, false>;
148 DominatorTree() = default;
149 explicit DominatorTree(Function
&F
) { recalculate(F
); }
150 explicit DominatorTree(DominatorTree
&DT
, DomTreeBuilder::BBUpdates U
) {
151 recalculate(*DT
.Parent
, U
);
154 /// Handle invalidation explicitly.
155 bool invalidate(Function
&F
, const PreservedAnalyses
&PA
,
156 FunctionAnalysisManager::Invalidator
&);
158 // Ensure base-class overloads are visible.
159 using Base::dominates
;
161 /// Return true if Def dominates a use in User.
163 /// This performs the special checks necessary if Def and User are in the same
164 /// basic block. Note that Def doesn't dominate a use in Def itself!
165 bool dominates(const Instruction
*Def
, const Use
&U
) const;
166 bool dominates(const Instruction
*Def
, const Instruction
*User
) const;
167 bool dominates(const Instruction
*Def
, const BasicBlock
*BB
) const;
169 /// Return true if an edge dominates a use.
171 /// If BBE is not a unique edge between start and end of the edge, it can
172 /// never dominate the use.
173 bool dominates(const BasicBlockEdge
&BBE
, const Use
&U
) const;
174 bool dominates(const BasicBlockEdge
&BBE
, const BasicBlock
*BB
) const;
176 // Ensure base class overloads are visible.
177 using Base::isReachableFromEntry
;
179 /// Provide an overload for a Use.
180 bool isReachableFromEntry(const Use
&U
) const;
182 // Pop up a GraphViz/gv window with the Dominator Tree rendered using `dot`.
183 void viewGraph(const Twine
&Name
, const Twine
&Title
);
187 //===-------------------------------------
188 // DominatorTree GraphTraits specializations so the DominatorTree can be
189 // iterable by generic graph iterators.
191 template <class Node
, class ChildIterator
> struct DomTreeGraphTraitsBase
{
192 using NodeRef
= Node
*;
193 using ChildIteratorType
= ChildIterator
;
194 using nodes_iterator
= df_iterator
<Node
*, df_iterator_default_set
<Node
*>>;
196 static NodeRef
getEntryNode(NodeRef N
) { return N
; }
197 static ChildIteratorType
child_begin(NodeRef N
) { return N
->begin(); }
198 static ChildIteratorType
child_end(NodeRef N
) { return N
->end(); }
200 static nodes_iterator
nodes_begin(NodeRef N
) {
201 return df_begin(getEntryNode(N
));
204 static nodes_iterator
nodes_end(NodeRef N
) { return df_end(getEntryNode(N
)); }
208 struct GraphTraits
<DomTreeNode
*>
209 : public DomTreeGraphTraitsBase
<DomTreeNode
, DomTreeNode::iterator
> {};
212 struct GraphTraits
<const DomTreeNode
*>
213 : public DomTreeGraphTraitsBase
<const DomTreeNode
,
214 DomTreeNode::const_iterator
> {};
216 template <> struct GraphTraits
<DominatorTree
*>
217 : public GraphTraits
<DomTreeNode
*> {
218 static NodeRef
getEntryNode(DominatorTree
*DT
) { return DT
->getRootNode(); }
220 static nodes_iterator
nodes_begin(DominatorTree
*N
) {
221 return df_begin(getEntryNode(N
));
224 static nodes_iterator
nodes_end(DominatorTree
*N
) {
225 return df_end(getEntryNode(N
));
229 /// Analysis pass which computes a \c DominatorTree.
230 class DominatorTreeAnalysis
: public AnalysisInfoMixin
<DominatorTreeAnalysis
> {
231 friend AnalysisInfoMixin
<DominatorTreeAnalysis
>;
232 static AnalysisKey Key
;
235 /// Provide the result typedef for this analysis pass.
236 using Result
= DominatorTree
;
238 /// Run the analysis pass over a function and produce a dominator tree.
239 DominatorTree
run(Function
&F
, FunctionAnalysisManager
&);
242 /// Printer pass for the \c DominatorTree.
243 class DominatorTreePrinterPass
244 : public PassInfoMixin
<DominatorTreePrinterPass
> {
248 explicit DominatorTreePrinterPass(raw_ostream
&OS
);
250 PreservedAnalyses
run(Function
&F
, FunctionAnalysisManager
&AM
);
253 /// Verifier pass for the \c DominatorTree.
254 struct DominatorTreeVerifierPass
: PassInfoMixin
<DominatorTreeVerifierPass
> {
255 PreservedAnalyses
run(Function
&F
, FunctionAnalysisManager
&AM
);
258 /// Legacy analysis pass which computes a \c DominatorTree.
259 class DominatorTreeWrapperPass
: public FunctionPass
{
265 DominatorTreeWrapperPass() : FunctionPass(ID
) {
266 initializeDominatorTreeWrapperPassPass(*PassRegistry::getPassRegistry());
269 DominatorTree
&getDomTree() { return DT
; }
270 const DominatorTree
&getDomTree() const { return DT
; }
272 bool runOnFunction(Function
&F
) override
;
274 void verifyAnalysis() const override
;
276 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
277 AU
.setPreservesAll();
280 void releaseMemory() override
{ DT
.releaseMemory(); }
282 void print(raw_ostream
&OS
, const Module
*M
= nullptr) const override
;
284 } // end namespace llvm
286 #endif // LLVM_IR_DOMINATORS_H