LLVM  14.0.0git
Dominators.cpp
Go to the documentation of this file.
1 //===- Dominators.cpp - Dominator Calculation -----------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements simple dominator construction algorithms for finding
10 // forward dominators. Postdominators are available in libanalysis, but are not
11 // included in libvmcore, because it's not needed. Forward dominators are
12 // needed to support the Verifier pass.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "llvm/IR/Dominators.h"
18 #include "llvm/ADT/SmallPtrSet.h"
19 #include "llvm/Config/llvm-config.h"
20 #include "llvm/IR/CFG.h"
21 #include "llvm/IR/Constants.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/PassManager.h"
24 #include "llvm/InitializePasses.h"
26 #include "llvm/Support/Debug.h"
29 #include <algorithm>
30 using namespace llvm;
31 
32 bool llvm::VerifyDomInfo = false;
35  cl::desc("Verify dominator info (time consuming)"));
36 
37 #ifdef EXPENSIVE_CHECKS
38 static constexpr bool ExpensiveChecksEnabled = true;
39 #else
40 static constexpr bool ExpensiveChecksEnabled = false;
41 #endif
42 
44  const Instruction *TI = Start->getTerminator();
45  unsigned NumEdgesToEnd = 0;
46  for (unsigned int i = 0, n = TI->getNumSuccessors(); i < n; ++i) {
47  if (TI->getSuccessor(i) == End)
48  ++NumEdgesToEnd;
49  if (NumEdgesToEnd >= 2)
50  return false;
51  }
52  assert(NumEdgesToEnd == 1);
53  return true;
54 }
55 
56 //===----------------------------------------------------------------------===//
57 // DominatorTree Implementation
58 //===----------------------------------------------------------------------===//
59 //
60 // Provide public access to DominatorTree information. Implementation details
61 // can be found in Dominators.h, GenericDomTree.h, and
62 // GenericDomTreeConstruction.h.
63 //
64 //===----------------------------------------------------------------------===//
65 
67 template class llvm::DominatorTreeBase<BasicBlock, false>; // DomTreeBase
68 template class llvm::DominatorTreeBase<BasicBlock, true>; // PostDomTreeBase
69 
70 template class llvm::cfg::Update<BasicBlock *>;
71 
72 template void llvm::DomTreeBuilder::Calculate<DomTreeBuilder::BBDomTree>(
74 template void
75 llvm::DomTreeBuilder::CalculateWithUpdates<DomTreeBuilder::BBDomTree>(
77 
78 template void llvm::DomTreeBuilder::Calculate<DomTreeBuilder::BBPostDomTree>(
80 // No CalculateWithUpdates<PostDomTree> instantiation, unless a usecase arises.
81 
82 template void llvm::DomTreeBuilder::InsertEdge<DomTreeBuilder::BBDomTree>(
84 template void llvm::DomTreeBuilder::InsertEdge<DomTreeBuilder::BBPostDomTree>(
86 
87 template void llvm::DomTreeBuilder::DeleteEdge<DomTreeBuilder::BBDomTree>(
89 template void llvm::DomTreeBuilder::DeleteEdge<DomTreeBuilder::BBPostDomTree>(
91 
92 template void llvm::DomTreeBuilder::ApplyUpdates<DomTreeBuilder::BBDomTree>(
95 template void llvm::DomTreeBuilder::ApplyUpdates<DomTreeBuilder::BBPostDomTree>(
98 
99 template bool llvm::DomTreeBuilder::Verify<DomTreeBuilder::BBDomTree>(
100  const DomTreeBuilder::BBDomTree &DT,
102 template bool llvm::DomTreeBuilder::Verify<DomTreeBuilder::BBPostDomTree>(
105 
108  // Check whether the analysis, all analyses on functions, or the function's
109  // CFG have been preserved.
110  auto PAC = PA.getChecker<DominatorTreeAnalysis>();
111  return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() ||
112  PAC.preservedSet<CFGAnalyses>());
113 }
114 
115 bool DominatorTree::dominates(const BasicBlock *BB, const Use &U) const {
116  Instruction *UserInst = cast<Instruction>(U.getUser());
117  if (auto *PN = dyn_cast<PHINode>(UserInst))
118  // A phi use using a value from a block is dominated by the end of that
119  // block. Note that the phi's parent block may not be.
120  return dominates(BB, PN->getIncomingBlock(U));
121  else
122  return properlyDominates(BB, UserInst->getParent());
123 }
124 
125 // dominates - Return true if Def dominates a use in User. This performs
126 // the special checks necessary if Def and User are in the same basic block.
127 // Note that Def doesn't dominate a use in Def itself!
129  const Instruction *User) const {
130  const Instruction *Def = dyn_cast<Instruction>(DefV);
131  if (!Def) {
132  assert((isa<Argument>(DefV) || isa<Constant>(DefV)) &&
133  "Should be called with an instruction, argument or constant");
134  return true; // Arguments and constants dominate everything.
135  }
136 
137  const BasicBlock *UseBB = User->getParent();
138  const BasicBlock *DefBB = Def->getParent();
139 
140  // Any unreachable use is dominated, even if Def == User.
141  if (!isReachableFromEntry(UseBB))
142  return true;
143 
144  // Unreachable definitions don't dominate anything.
145  if (!isReachableFromEntry(DefBB))
146  return false;
147 
148  // An instruction doesn't dominate a use in itself.
149  if (Def == User)
150  return false;
151 
152  // The value defined by an invoke dominates an instruction only if it
153  // dominates every instruction in UseBB.
154  // A PHI is dominated only if the instruction dominates every possible use in
155  // the UseBB.
156  if (isa<InvokeInst>(Def) || isa<CallBrInst>(Def) || isa<PHINode>(User))
157  return dominates(Def, UseBB);
158 
159  if (DefBB != UseBB)
160  return dominates(DefBB, UseBB);
161 
162  return Def->comesBefore(User);
163 }
164 
165 // true if Def would dominate a use in any instruction in UseBB.
166 // note that dominates(Def, Def->getParent()) is false.
168  const BasicBlock *UseBB) const {
169  const BasicBlock *DefBB = Def->getParent();
170 
171  // Any unreachable use is dominated, even if DefBB == UseBB.
172  if (!isReachableFromEntry(UseBB))
173  return true;
174 
175  // Unreachable definitions don't dominate anything.
176  if (!isReachableFromEntry(DefBB))
177  return false;
178 
179  if (DefBB == UseBB)
180  return false;
181 
182  // Invoke results are only usable in the normal destination, not in the
183  // exceptional destination.
184  if (const auto *II = dyn_cast<InvokeInst>(Def)) {
185  BasicBlock *NormalDest = II->getNormalDest();
186  BasicBlockEdge E(DefBB, NormalDest);
187  return dominates(E, UseBB);
188  }
189 
190  // Callbr results are similarly only usable in the default destination.
191  if (const auto *CBI = dyn_cast<CallBrInst>(Def)) {
192  BasicBlock *NormalDest = CBI->getDefaultDest();
193  BasicBlockEdge E(DefBB, NormalDest);
194  return dominates(E, UseBB);
195  }
196 
197  return dominates(DefBB, UseBB);
198 }
199 
201  const BasicBlock *UseBB) const {
202  // If the BB the edge ends in doesn't dominate the use BB, then the
203  // edge also doesn't.
204  const BasicBlock *Start = BBE.getStart();
205  const BasicBlock *End = BBE.getEnd();
206  if (!dominates(End, UseBB))
207  return false;
208 
209  // Simple case: if the end BB has a single predecessor, the fact that it
210  // dominates the use block implies that the edge also does.
211  if (End->getSinglePredecessor())
212  return true;
213 
214  // The normal edge from the invoke is critical. Conceptually, what we would
215  // like to do is split it and check if the new block dominates the use.
216  // With X being the new block, the graph would look like:
217  //
218  // DefBB
219  // /\ . .
220  // / \ . .
221  // / \ . .
222  // / \ | |
223  // A X B C
224  // | \ | /
225  // . \|/
226  // . NormalDest
227  // .
228  //
229  // Given the definition of dominance, NormalDest is dominated by X iff X
230  // dominates all of NormalDest's predecessors (X, B, C in the example). X
231  // trivially dominates itself, so we only have to find if it dominates the
232  // other predecessors. Since the only way out of X is via NormalDest, X can
233  // only properly dominate a node if NormalDest dominates that node too.
234  int IsDuplicateEdge = 0;
235  for (const BasicBlock *BB : predecessors(End)) {
236  if (BB == Start) {
237  // If there are multiple edges between Start and End, by definition they
238  // can't dominate anything.
239  if (IsDuplicateEdge++)
240  return false;
241  continue;
242  }
243 
244  if (!dominates(End, BB))
245  return false;
246  }
247  return true;
248 }
249 
250 bool DominatorTree::dominates(const BasicBlockEdge &BBE, const Use &U) const {
251  Instruction *UserInst = cast<Instruction>(U.getUser());
252  // A PHI in the end of the edge is dominated by it.
253  PHINode *PN = dyn_cast<PHINode>(UserInst);
254  if (PN && PN->getParent() == BBE.getEnd() &&
255  PN->getIncomingBlock(U) == BBE.getStart())
256  return true;
257 
258  // Otherwise use the edge-dominates-block query, which
259  // handles the crazy critical edge cases properly.
260  const BasicBlock *UseBB;
261  if (PN)
262  UseBB = PN->getIncomingBlock(U);
263  else
264  UseBB = UserInst->getParent();
265  return dominates(BBE, UseBB);
266 }
267 
268 bool DominatorTree::dominates(const Value *DefV, const Use &U) const {
269  const Instruction *Def = dyn_cast<Instruction>(DefV);
270  if (!Def) {
271  assert((isa<Argument>(DefV) || isa<Constant>(DefV)) &&
272  "Should be called with an instruction, argument or constant");
273  return true; // Arguments and constants dominate everything.
274  }
275 
276  Instruction *UserInst = cast<Instruction>(U.getUser());
277  const BasicBlock *DefBB = Def->getParent();
278 
279  // Determine the block in which the use happens. PHI nodes use
280  // their operands on edges; simulate this by thinking of the use
281  // happening at the end of the predecessor block.
282  const BasicBlock *UseBB;
283  if (PHINode *PN = dyn_cast<PHINode>(UserInst))
284  UseBB = PN->getIncomingBlock(U);
285  else
286  UseBB = UserInst->getParent();
287 
288  // Any unreachable use is dominated, even if Def == User.
289  if (!isReachableFromEntry(UseBB))
290  return true;
291 
292  // Unreachable definitions don't dominate anything.
293  if (!isReachableFromEntry(DefBB))
294  return false;
295 
296  // Invoke instructions define their return values on the edges to their normal
297  // successors, so we have to handle them specially.
298  // Among other things, this means they don't dominate anything in
299  // their own block, except possibly a phi, so we don't need to
300  // walk the block in any case.
301  if (const InvokeInst *II = dyn_cast<InvokeInst>(Def)) {
302  BasicBlock *NormalDest = II->getNormalDest();
303  BasicBlockEdge E(DefBB, NormalDest);
304  return dominates(E, U);
305  }
306 
307  // Callbr results are similarly only usable in the default destination.
308  if (const auto *CBI = dyn_cast<CallBrInst>(Def)) {
309  BasicBlock *NormalDest = CBI->getDefaultDest();
310  BasicBlockEdge E(DefBB, NormalDest);
311  return dominates(E, U);
312  }
313 
314  // If the def and use are in different blocks, do a simple CFG dominator
315  // tree query.
316  if (DefBB != UseBB)
317  return dominates(DefBB, UseBB);
318 
319  // Ok, def and use are in the same block. If the def is an invoke, it
320  // doesn't dominate anything in the block. If it's a PHI, it dominates
321  // everything in the block.
322  if (isa<PHINode>(UserInst))
323  return true;
324 
325  return Def->comesBefore(UserInst);
326 }
327 
329  Instruction *I = dyn_cast<Instruction>(U.getUser());
330 
331  // ConstantExprs aren't really reachable from the entry block, but they
332  // don't need to be treated like unreachable code either.
333  if (!I) return true;
334 
335  // PHI nodes use their operands on their incoming edges.
336  if (PHINode *PN = dyn_cast<PHINode>(I))
337  return isReachableFromEntry(PN->getIncomingBlock(U));
338 
339  // Everything else uses their operands in their own block.
340  return isReachableFromEntry(I->getParent());
341 }
342 
343 // Edge BBE1 dominates edge BBE2 if they match or BBE1 dominates start of BBE2.
345  const BasicBlockEdge &BBE2) const {
346  if (BBE1.getStart() == BBE2.getStart() && BBE1.getEnd() == BBE2.getEnd())
347  return true;
348  return dominates(BBE1, BBE2.getStart());
349 }
350 
351 //===----------------------------------------------------------------------===//
352 // DominatorTreeAnalysis and related pass implementations
353 //===----------------------------------------------------------------------===//
354 //
355 // This implements the DominatorTreeAnalysis which is used with the new pass
356 // manager. It also implements some methods from utility passes.
357 //
358 //===----------------------------------------------------------------------===//
359 
362  DominatorTree DT;
363  DT.recalculate(F);
364  return DT;
365 }
366 
367 AnalysisKey DominatorTreeAnalysis::Key;
368 
370 
373  OS << "DominatorTree for function: " << F.getName() << "\n";
375 
376  return PreservedAnalyses::all();
377 }
378 
381  auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
382  assert(DT.verify());
383  (void)DT;
384  return PreservedAnalyses::all();
385 }
386 
387 //===----------------------------------------------------------------------===//
388 // DominatorTreeWrapperPass Implementation
389 //===----------------------------------------------------------------------===//
390 //
391 // The implementation details of the wrapper pass that holds a DominatorTree
392 // suitable for use with the legacy pass manager.
393 //
394 //===----------------------------------------------------------------------===//
395 
397 
400 }
401 
403  "Dominator Tree Construction", true, true)
404 
406  DT.recalculate(F);
407  return false;
408 }
409 
411  if (VerifyDomInfo)
413  else if (ExpensiveChecksEnabled)
415 }
416 
418  DT.print(OS);
419 }
i
i
Definition: README.txt:29
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:155
INITIALIZE_PASS
INITIALIZE_PASS(DominatorTreeWrapperPass, "domtree", "Dominator Tree Construction", true, true) bool DominatorTreeWrapperPass
Definition: Dominators.cpp:402
llvm::DominatorTreeWrapperPass::ID
static char ID
Definition: Dominators.h:285
llvm::predecessors
pred_range predecessors(BasicBlock *BB)
Definition: CFG.h:127
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::tgtok::Def
@ Def
Definition: TGLexer.h:50
llvm::DominatorTreeBase::print
void print(raw_ostream &O) const
print - Convert to human readable form
Definition: GenericDomTree.h:709
print
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Definition: ArchiveWriter.cpp:147
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:769
llvm::Function
Definition: Function.h:61
llvm::cl::location
LocationClass< Ty > location(Ty &L)
Definition: CommandLine.h:459
llvm::DomTreeBuilder::BBUpdates
ArrayRef< llvm::cfg::Update< BasicBlock * > > BBUpdates
Definition: Dominators.h:45
llvm::AllAnalysesOn
This templated class represents "all analyses that operate over <a particular IR unit>" (e....
Definition: PassManager.h:93
llvm::DominatorTree::invalidate
bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &)
Handle invalidation explicitly.
Definition: Dominators.cpp:106
llvm::DominatorTree
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:151
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
VerifyDomInfoX
static cl::opt< bool, true > VerifyDomInfoX("verify-dom-info", cl::location(VerifyDomInfo), cl::Hidden, cl::desc("Verify dominator info (time consuming)"))
llvm::BasicBlockEdge
Definition: Dominators.h:83
llvm::JumpTable::Full
@ Full
Definition: TargetOptions.h:50
DepthFirstIterator.h
llvm::DominatorTreeWrapperPass::print
void print(raw_ostream &OS, const Module *M=nullptr) const override
print - Print out the internal state of the pass.
Definition: Dominators.cpp:417
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::GraphDiff
Definition: CFGDiff.h:57
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
llvm::DominatorTree::dominates
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Definition: Dominators.cpp:115
CommandLine.h
llvm::Instruction::getNumSuccessors
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
Definition: Instruction.cpp:765
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
Constants.h
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::User
Definition: User.h:44
llvm::Instruction
Definition: Instruction.h:45
llvm::DominatorTreeWrapperPass
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:281
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::Use::getUser
User * getUser() const
Returns the User that contains this Use.
Definition: Use.h:73
SmallPtrSet.h
llvm::Instruction::getSuccessor
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
Definition: Instruction.cpp:777
llvm::BasicBlockEdge::getStart
const BasicBlock * getStart() const
Definition: Dominators.h:97
llvm::AnalysisManager::Invalidator
API to communicate dependencies between analyses during invalidation.
Definition: PassManager.h:656
llvm::DominatorTreePrinterPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: Dominators.cpp:371
CFG.h
llvm::InvokeInst
Invoke instruction.
Definition: Instructions.h:3743
llvm::cl::opt
Definition: CommandLine.h:1422
llvm::AnalysisKey
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: PassManager.h:72
I
#define I(x, y, z)
Definition: MD5.cpp:59
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::DominatorTree::isReachableFromEntry
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
Definition: Dominators.cpp:328
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::DominatorTreeAnalysis::run
DominatorTree run(Function &F, FunctionAnalysisManager &)
Run the analysis pass over a function and produce a dominator tree.
Definition: Dominators.cpp:360
llvm::DominatorTreeBase::recalculate
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
Definition: GenericDomTree.h:778
llvm::BasicBlockEdge::getEnd
const BasicBlock * getEnd() const
Definition: Dominators.h:101
llvm::CFGAnalyses
Represents analyses that only rely on functions' control flow.
Definition: PassManager.h:116
llvm::DominatorTreeWrapperPass::verifyAnalysis
void verifyAnalysis() const override
verifyAnalysis() - This member can be implemented by a analysis pass to check state of analysis infor...
Definition: Dominators.cpp:410
llvm::DominatorTreeBase< BasicBlock, false >
llvm::DominatorTreeBase< BasicBlock, false >::properlyDominates
bool properlyDominates(const DomTreeNodeBase< BasicBlock > *A, const DomTreeNodeBase< BasicBlock > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
Definition: GenericDomTree.h:392
ExpensiveChecksEnabled
static constexpr bool ExpensiveChecksEnabled
Definition: Dominators.cpp:40
llvm::DomTreeNodeBase< BasicBlock >
llvm::BasicBlock::getTerminator
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:148
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::BasicBlockEdge::isSingleEdge
bool isSingleEdge() const
Check if this is the only edge between Start and End.
Definition: Dominators.cpp:43
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:161
PassManager.h
llvm::initializeDominatorTreeWrapperPassPass
void initializeDominatorTreeWrapperPassPass(PassRegistry &)
GenericDomTreeConstruction.h
llvm::DominatorTreeBase::VerificationLevel
VerificationLevel
Definition: GenericDomTree.h:245
llvm::DominatorTreeAnalysis
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:252
Instructions.h
llvm::DominatorTreePrinterPass::DominatorTreePrinterPass
DominatorTreePrinterPass(raw_ostream &OS)
Definition: Dominators.cpp:369
Dominators.h
llvm::codeview::Basic
@ Basic
Definition: CodeView.h:152
llvm::Instruction::getParent
const BasicBlock * getParent() const
Definition: Instruction.h:94
llvm::PHINode::getIncomingBlock
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Definition: Instructions.h:2743
llvm::DominatorTreeBase::verify
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
Definition: GenericDomTree.h:802
llvm::PHINode
Definition: Instructions.h:2627
llvm::PreservedAnalyses::getChecker
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
Definition: PassManager.h:313
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:44
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::cfg::Update
Definition: CFGUpdate.h:28
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
From
BlockVerifier::State From
Definition: BlockVerifier.cpp:55
llvm::cl::desc
Definition: CommandLine.h:414
raw_ostream.h
n
The same transformation can work with an even modulo with the addition of a and shrink the compare RHS by the same amount Unless the target supports that transformation probably isn t worthwhile The transformation can also easily be made to work with non zero equality for n
Definition: README.txt:685
llvm::DominatorTreeVerifierPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: Dominators.cpp:379
InitializePasses.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
Debug.h
llvm::VerifyDomInfo
bool VerifyDomInfo
Enables verification of dominator trees.
Definition: Dominators.cpp:32
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38
llvm::DominatorTreeWrapperPass::DominatorTreeWrapperPass
DominatorTreeWrapperPass()
Definition: Dominators.cpp:398