LLVM 22.0.0git
MachineTraceMetrics.h
Go to the documentation of this file.
1//===- lib/CodeGen/MachineTraceMetrics.h - Super-scalar metrics -*- C++ -*-===//
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 defines the interface for the MachineTraceMetrics analysis pass
10// that estimates CPU resource usage and critical data dependency paths through
11// preferred traces. This is useful for super-scalar CPUs where execution speed
12// can be limited both by data dependencies and by limited execution resources.
13//
14// Out-of-order CPUs will often be executing instructions from multiple basic
15// blocks at the same time. This makes it difficult to estimate the resource
16// usage accurately in a single basic block. Resources can be estimated better
17// by looking at a trace through the current basic block.
18//
19// For every block, the MachineTraceMetrics pass will pick a preferred trace
20// that passes through the block. The trace is chosen based on loop structure,
21// branch probabilities, and resource usage. The intention is to pick likely
22// traces that would be the most affected by code transformations.
23//
24// It is expensive to compute a full arbitrary trace for every block, so to
25// save some computations, traces are chosen to be convergent. This means that
26// if the traces through basic blocks A and B ever cross when moving away from
27// A and B, they never diverge again. This applies in both directions - If the
28// traces meet above A and B, they won't diverge when going further back.
29//
30// Traces tend to align with loops. The trace through a block in an inner loop
31// will begin at the loop entry block and end at a back edge. If there are
32// nested loops, the trace may begin and end at those instead.
33//
34// For each trace, we compute the critical path length, which is the number of
35// cycles required to execute the trace when execution is limited by data
36// dependencies only. We also compute the resource height, which is the number
37// of cycles required to execute all instructions in the trace when ignoring
38// data dependencies.
39//
40// Every instruction in the current block has a slack - the number of cycles
41// execution of the instruction can be delayed without extending the critical
42// path.
43//
44//===----------------------------------------------------------------------===//
45
46#ifndef LLVM_CODEGEN_MACHINETRACEMETRICS_H
47#define LLVM_CODEGEN_MACHINETRACEMETRICS_H
48
49#include "llvm/ADT/ArrayRef.h"
50#include "llvm/ADT/DenseMap.h"
52#include "llvm/ADT/SparseSet.h"
57
58namespace llvm {
59
60class AnalysisUsage;
61class MachineFunction;
62class MachineInstr;
63class MachineLoop;
64class MachineLoopInfo;
66struct MCSchedClassDesc;
67class raw_ostream;
68class TargetInstrInfo;
70
71// Keep track of physreg data dependencies by recording each live register unit.
72// Associate each regunit with an instruction operand. Depending on the
73// direction instructions are scanned, it could be the operand that defined the
74// regunit, or the highest operand to read the regunit.
76 MCRegUnit RegUnit;
77 unsigned Cycle = 0;
78 const MachineInstr *MI = nullptr;
79 unsigned Op = 0;
80
81 unsigned getSparseSetIndex() const { return static_cast<unsigned>(RegUnit); }
82
83 explicit LiveRegUnit(MCRegUnit RU) : RegUnit(RU) {}
84};
85
87
88/// Strategies for selecting traces.
90 /// Select the trace through a block that has the fewest instructions.
92 /// Select the trace that contains only the current basic block. For instance,
93 /// this strategy can be used by MachineCombiner to make better decisions when
94 /// we estimate critical path for in-order cores.
97};
98
100 const MachineFunction *MF = nullptr;
101 const TargetInstrInfo *TII = nullptr;
102 const TargetRegisterInfo *TRI = nullptr;
103 const MachineRegisterInfo *MRI = nullptr;
104 const MachineLoopInfo *Loops = nullptr;
105 TargetSchedModel SchedModel;
106
107public:
109 friend class Ensemble;
110 friend class Trace;
111
112 class Ensemble;
113
114 // For legacy pass.
116
118 init(MF, LI);
119 }
120
122
124
125 void init(MachineFunction &Func, const MachineLoopInfo &LI);
126 void clear();
127
128 /// Per-basic block information that doesn't depend on the trace through the
129 /// block.
131 /// The number of non-trivial instructions in the block.
132 /// Doesn't count PHI and COPY instructions that are likely to be removed.
133 unsigned InstrCount = ~0u;
134
135 /// True when the block contains calls.
136 bool HasCalls = false;
137
138 FixedBlockInfo() = default;
139
140 /// Returns true when resource information for this block has been computed.
141 bool hasResources() const { return InstrCount != ~0u; }
142
143 /// Invalidate resource information.
144 void invalidate() { InstrCount = ~0u; }
145 };
146
147 /// Get the fixed resource information about MBB. Compute it on demand.
148 const FixedBlockInfo *getResources(const MachineBasicBlock*);
149
150 /// Get the scaled number of cycles used per processor resource in MBB.
151 /// This is an array with SchedModel.getNumProcResourceKinds() entries.
152 /// The getResources() function above must have been called first.
153 ///
154 /// These numbers have already been scaled by SchedModel.getResourceFactor().
155 ArrayRef<unsigned> getProcReleaseAtCycles(unsigned MBBNum) const;
156
157 /// A virtual register or regunit required by a basic block or its trace
158 /// successors.
159 struct LiveInReg {
160 /// The virtual register required, or a register unit.
162
163 /// For virtual registers: Minimum height of the defining instruction.
164 /// For regunits: Height of the highest user in the trace.
165 unsigned Height;
166
169 };
170
171 /// Per-basic block information that relates to a specific trace through the
172 /// block. Convergent traces means that only one of these is required per
173 /// block in a trace ensemble.
175 /// Trace predecessor, or NULL for the first block in the trace.
176 /// Valid when hasValidDepth().
177 const MachineBasicBlock *Pred = nullptr;
178
179 /// Trace successor, or NULL for the last block in the trace.
180 /// Valid when hasValidHeight().
181 const MachineBasicBlock *Succ = nullptr;
182
183 /// The block number of the head of the trace. (When hasValidDepth()).
184 unsigned Head;
185
186 /// The block number of the tail of the trace. (When hasValidHeight()).
187 unsigned Tail;
188
189 /// Accumulated number of instructions in the trace above this block.
190 /// Does not include instructions in this block.
191 unsigned InstrDepth = ~0u;
192
193 /// Accumulated number of instructions in the trace below this block.
194 /// Includes instructions in this block.
195 unsigned InstrHeight = ~0u;
196
197 TraceBlockInfo() = default;
198
199 /// Returns true if the depth resources have been computed from the trace
200 /// above this block.
201 bool hasValidDepth() const { return InstrDepth != ~0u; }
202
203 /// Returns true if the height resources have been computed from the trace
204 /// below this block.
205 bool hasValidHeight() const { return InstrHeight != ~0u; }
206
207 /// Invalidate depth resources when some block above this one has changed.
209
210 /// Invalidate height resources when a block below this one has changed.
212
213 /// Assuming that this is a dominator of TBI, determine if it contains
214 /// useful instruction depths. A dominating block can be above the current
215 /// trace head, and any dependencies from such a far away dominator are not
216 /// expected to affect the critical path.
217 ///
218 /// Also returns true when TBI == this.
219 bool isUsefulDominator(const TraceBlockInfo &TBI) const {
220 // The trace for TBI may not even be calculated yet.
221 if (!hasValidDepth() || !TBI.hasValidDepth())
222 return false;
223 // Instruction depths are only comparable if the traces share a head.
224 if (Head != TBI.Head)
225 return false;
226 // It is almost always the case that TBI belongs to the same trace as
227 // this block, but rare convoluted cases involving irreducible control
228 // flow, a dominator may share a trace head without actually being on the
229 // same trace as TBI. This is not a big problem as long as it doesn't
230 // increase the instruction depth.
232 }
233
234 // Data-dependency-related information. Per-instruction depth and height
235 // are computed from data dependencies in the current trace, using
236 // itinerary data.
237
238 /// Instruction depths have been computed. This implies hasValidDepth().
240
241 /// Instruction heights have been computed. This implies hasValidHeight().
243
244 /// Critical path length. This is the number of cycles in the longest data
245 /// dependency chain through the trace. This is only valid when both
246 /// HasValidInstrDepths and HasValidInstrHeights are set.
247 unsigned CriticalPath;
248
249 /// Live-in registers. These registers are defined above the current block
250 /// and used by this block or a block below it.
251 /// This does not include PHI uses in the current block, but it does
252 /// include PHI uses in deeper blocks.
254
255 void print(raw_ostream&) const;
256 void dump() const { print(dbgs()); }
257 };
258
259 /// InstrCycles represents the cycle height and depth of an instruction in a
260 /// trace.
261 struct InstrCycles {
262 /// Earliest issue cycle as determined by data dependencies and instruction
263 /// latencies from the beginning of the trace. Data dependencies from
264 /// before the trace are not included.
265 unsigned Depth;
266
267 /// Minimum number of cycles from this instruction is issued to the of the
268 /// trace, as determined by data dependencies and instruction latencies.
269 unsigned Height;
270 };
271
272 /// A trace represents a plausible sequence of executed basic blocks that
273 /// passes through the current basic block one. The Trace class serves as a
274 /// handle to internal cached data structures.
275 class Trace {
276 Ensemble &TE;
277 TraceBlockInfo &TBI;
278
279 unsigned getBlockNum() const { return &TBI - &TE.BlockInfo[0]; }
280
281 public:
282 explicit Trace(Ensemble &te, TraceBlockInfo &tbi) : TE(te), TBI(tbi) {}
283
284 void print(raw_ostream&) const;
285 void dump() const { print(dbgs()); }
286
287 /// Compute the total number of instructions in the trace.
288 unsigned getInstrCount() const {
289 return TBI.InstrDepth + TBI.InstrHeight;
290 }
291
292 /// Return the resource depth of the top/bottom of the trace center block.
293 /// This is the number of cycles required to execute all instructions from
294 /// the trace head to the trace center block. The resource depth only
295 /// considers execution resources, it ignores data dependencies.
296 /// When Bottom is set, instructions in the trace center block are included.
297 unsigned getResourceDepth(bool Bottom) const;
298
299 /// Return the resource length of the trace. This is the number of cycles
300 /// required to execute the instructions in the trace if they were all
301 /// independent, exposing the maximum instruction-level parallelism.
302 ///
303 /// Any blocks in Extrablocks are included as if they were part of the
304 /// trace. Likewise, extra resources required by the specified scheduling
305 /// classes are included. For the caller to account for extra machine
306 /// instructions, it must first resolve each instruction's scheduling class.
307 unsigned getResourceLength(
309 ArrayRef<const MCSchedClassDesc *> ExtraInstrs = {},
310 ArrayRef<const MCSchedClassDesc *> RemoveInstrs = {}) const;
311
312 /// Return the length of the (data dependency) critical path through the
313 /// trace.
314 unsigned getCriticalPath() const { return TBI.CriticalPath; }
315
316 /// Return the depth and height of MI. The depth is only valid for
317 /// instructions in or above the trace center block. The height is only
318 /// valid for instructions in or below the trace center block.
320 return TE.Cycles.lookup(&MI);
321 }
322
323 /// Return the slack of MI. This is the number of cycles MI can be delayed
324 /// before the critical path becomes longer.
325 /// MI must be an instruction in the trace center block.
326 unsigned getInstrSlack(const MachineInstr &MI) const;
327
328 /// Return the Depth of a PHI instruction in a trace center block successor.
329 /// The PHI does not have to be part of the trace.
330 unsigned getPHIDepth(const MachineInstr &PHI) const;
331
332 /// A dependence is useful if the basic block of the defining instruction
333 /// is part of the trace of the user instruction. It is assumed that DefMI
334 /// dominates UseMI (see also isUsefulDominator).
335 bool isDepInTrace(const MachineInstr &DefMI,
336 const MachineInstr &UseMI) const;
337 };
338
339 /// A trace ensemble is a collection of traces selected using the same
340 /// strategy, for example 'minimum resource height'. There is one trace for
341 /// every block in the function.
342 class Ensemble {
343 friend class Trace;
344
347 SmallVector<unsigned, 0> ProcResourceDepths;
348 SmallVector<unsigned, 0> ProcResourceHeights;
349
350 void computeTrace(const MachineBasicBlock*);
351 void computeDepthResources(const MachineBasicBlock*);
352 void computeHeightResources(const MachineBasicBlock*);
353 unsigned computeCrossBlockCriticalPath(const TraceBlockInfo&);
354 void computeInstrDepths(const MachineBasicBlock*);
355 void computeInstrHeights(const MachineBasicBlock*);
356 void addLiveIns(const MachineInstr *DefMI, unsigned DefOp,
358
359 protected:
361
362 explicit Ensemble(MachineTraceMetrics*);
363
366 const MachineLoop *getLoopFor(const MachineBasicBlock*) const;
369 ArrayRef<unsigned> getProcResourceDepths(unsigned MBBNum) const;
370 ArrayRef<unsigned> getProcResourceHeights(unsigned MBBNum) const;
371
372 public:
373 virtual ~Ensemble();
374
375 virtual const char *getName() const = 0;
376 void print(raw_ostream &) const;
377 void dump() const { print(dbgs()); }
378 void invalidate(const MachineBasicBlock *MBB);
379 void verify() const;
380
381 /// Get the trace that passes through MBB.
382 /// The trace is computed on demand.
384
385 /// Updates the depth of an machine instruction, given RegUnits.
386 void updateDepth(TraceBlockInfo &TBI, const MachineInstr &,
387 LiveRegUnitSet &RegUnits);
388 void updateDepth(const MachineBasicBlock *, const MachineInstr &,
389 LiveRegUnitSet &RegUnits);
390
391 /// Updates the depth of the instructions from Start to End.
394 LiveRegUnitSet &RegUnits);
395 };
396
397 /// Get the trace ensemble representing the given trace selection strategy.
398 /// The returned Ensemble object is owned by the MachineTraceMetrics analysis,
399 /// and valid for the lifetime of the analysis pass.
401
402 /// Invalidate cached information about MBB. This must be called *before* MBB
403 /// is erased, or the CFG is otherwise changed.
404 ///
405 /// This invalidates per-block information about resource usage for MBB only,
406 /// and it invalidates per-trace information for any trace that passes
407 /// through MBB.
408 ///
409 /// Call Ensemble::getTrace() again to update any trace handles.
410 void invalidate(const MachineBasicBlock *MBB);
411
412 /// Handle invalidation explicitly.
414 MachineFunctionAnalysisManager::Invalidator &);
415
416 void verifyAnalysis() const;
417
418private:
419 // One entry per basic block, indexed by block number.
421
422 // Cycles consumed on each processor resource per block.
423 // The number of processor resource kinds is constant for a given subtarget,
424 // but it is not known at compile time. The number of cycles consumed by
425 // block B on processor resource R is at ProcReleaseAtCycles[B*Kinds + R]
426 // where Kinds = SchedModel.getNumProcResourceKinds().
427 SmallVector<unsigned, 0> ProcReleaseAtCycles;
428
429 // One ensemble per strategy.
430 std::unique_ptr<Ensemble>
431 Ensembles[static_cast<size_t>(MachineTraceStrategy::TS_NumStrategies)];
432
433 // Convert scaled resource usage to a cycle count that can be compared with
434 // latencies.
435 unsigned getCycles(unsigned Scaled) {
436 unsigned Factor = SchedModel.getLatencyFactor();
437 return (Scaled + Factor - 1) / Factor;
438 }
439};
440
442 const MachineTraceMetrics::Trace &Tr) {
443 Tr.print(OS);
444 return OS;
445}
446
449 En.print(OS);
450 return OS;
451}
452
454 : public AnalysisInfoMixin<MachineTraceMetricsAnalysis> {
456 static AnalysisKey Key;
457
458public:
461};
462
463/// Verifier pass for \c MachineTraceMetrics.
465 : PassInfoMixin<MachineTraceMetricsVerifierPass> {
468 static bool isRequired() { return true; }
469};
470
472public:
473 static char ID;
475
477
478 void getAnalysisUsage(AnalysisUsage &) const override;
479 bool runOnMachineFunction(MachineFunction &) override;
480 void releaseMemory() override { MTM.clear(); }
481 void verifyAnalysis() const override { MTM.verifyAnalysis(); }
483};
484
485} // end namespace llvm
486
487#endif // LLVM_CODEGEN_MACHINETRACEMETRICS_H
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
Rewrite undef for PHI
@ Scaled
MachineBasicBlock & MBB
This file defines the DenseMap class.
IRTranslator LLVM IR MI
LiveInRegUnits addLiveIns(MBB)
This file defines the SmallVector class.
This file defines the SparseSet class derived from the version described in Briggs,...
Represent the analysis usage information of a pass.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
MachineInstrBundleIterator< MachineInstr > iterator
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
void getAnalysisUsage(AnalysisUsage &) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool runOnMachineFunction(MachineFunction &) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void verifyAnalysis() const override
verifyAnalysis() - This member can be implemented by a analysis pass to check state of analysis infor...
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
A trace ensemble is a collection of traces selected using the same strategy, for example 'minimum res...
void invalidate(const MachineBasicBlock *MBB)
Invalidate traces through BadMBB.
ArrayRef< unsigned > getProcResourceHeights(unsigned MBBNum) const
Get an array of processor resource heights for MBB.
virtual const MachineBasicBlock * pickTracePred(const MachineBasicBlock *)=0
void updateDepth(TraceBlockInfo &TBI, const MachineInstr &, LiveRegUnitSet &RegUnits)
Updates the depth of an machine instruction, given RegUnits.
const MachineLoop * getLoopFor(const MachineBasicBlock *) const
void updateDepths(MachineBasicBlock::iterator Start, MachineBasicBlock::iterator End, LiveRegUnitSet &RegUnits)
Updates the depth of the instructions from Start to End.
const TraceBlockInfo * getHeightResources(const MachineBasicBlock *) const
const TraceBlockInfo * getDepthResources(const MachineBasicBlock *) const
virtual const char * getName() const =0
ArrayRef< unsigned > getProcResourceDepths(unsigned MBBNum) const
Get an array of processor resource depths for MBB.
virtual const MachineBasicBlock * pickTraceSucc(const MachineBasicBlock *)=0
Trace getTrace(const MachineBasicBlock *MBB)
Get the trace that passes through MBB.
A trace represents a plausible sequence of executed basic blocks that passes through the current basi...
unsigned getInstrCount() const
Compute the total number of instructions in the trace.
unsigned getResourceLength(ArrayRef< const MachineBasicBlock * > Extrablocks={}, ArrayRef< const MCSchedClassDesc * > ExtraInstrs={}, ArrayRef< const MCSchedClassDesc * > RemoveInstrs={}) const
Return the resource length of the trace.
InstrCycles getInstrCycles(const MachineInstr &MI) const
Return the depth and height of MI.
unsigned getInstrSlack(const MachineInstr &MI) const
Return the slack of MI.
bool isDepInTrace(const MachineInstr &DefMI, const MachineInstr &UseMI) const
A dependence is useful if the basic block of the defining instruction is part of the trace of the use...
Trace(Ensemble &te, TraceBlockInfo &tbi)
unsigned getCriticalPath() const
Return the length of the (data dependency) critical path through the trace.
unsigned getPHIDepth(const MachineInstr &PHI) const
Return the Depth of a PHI instruction in a trace center block successor.
unsigned getResourceDepth(bool Bottom) const
Return the resource depth of the top/bottom of the trace center block.
MachineTraceMetrics(MachineTraceMetrics &&)=default
Ensemble * getEnsemble(MachineTraceStrategy)
Get the trace ensemble representing the given trace selection strategy.
void invalidate(const MachineBasicBlock *MBB)
Invalidate cached information about MBB.
const FixedBlockInfo * getResources(const MachineBasicBlock *)
Get the fixed resource information about MBB. Compute it on demand.
ArrayRef< unsigned > getProcReleaseAtCycles(unsigned MBBNum) const
Get the scaled number of cycles used per processor resource in MBB.
void init(MachineFunction &Func, const MachineLoopInfo &LI)
MachineTraceMetrics(MachineFunction &MF, const MachineLoopInfo &LI)
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
SparseSet - Fast set implementation for objects that can be identified by small unsigned keys.
Definition SparseSet.h:117
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Provide an instruction scheduling machine model to CodeGen passes.
unsigned getLatencyFactor() const
Multiply cycle count by this factor to normalize it relative to other resources.
Wrapper class representing a virtual register or register unit.
Definition Register.h:181
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
MachineTraceStrategy
Strategies for selecting traces.
@ TS_MinInstrCount
Select the trace through a block that has the fewest instructions.
@ TS_Local
Select the trace that contains only the current basic block.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
SparseSet< LiveRegUnit, MCRegUnit, MCRegUnitToIndex > LiveRegUnitSet
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
ArrayRef(const T &OneElt) -> ArrayRef< T >
A CRTP mix-in that provides informational APIs needed for analysis passes.
Definition PassManager.h:92
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29
unsigned getSparseSetIndex() const
const MachineInstr * MI
LiveRegUnit(MCRegUnit RU)
Summarize the scheduling resources required for an instruction of a particular scheduling class.
Definition MCSchedule.h:123
Verifier pass for MachineTraceMetrics.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
bool hasResources() const
Returns true when resource information for this block has been computed.
unsigned InstrCount
The number of non-trivial instructions in the block.
void invalidate()
Invalidate resource information.
bool HasCalls
True when the block contains calls.
InstrCycles represents the cycle height and depth of an instruction in a trace.
unsigned Height
Minimum number of cycles from this instruction is issued to the of the trace, as determined by data d...
unsigned Depth
Earliest issue cycle as determined by data dependencies and instruction latencies from the beginning ...
LiveInReg(VirtRegOrUnit VRegOrUnit, unsigned Height=0)
unsigned Height
For virtual registers: Minimum height of the defining instruction.
VirtRegOrUnit VRegOrUnit
The virtual register required, or a register unit.
Per-basic block information that relates to a specific trace through the block.
unsigned InstrDepth
Accumulated number of instructions in the trace above this block.
void invalidateDepth()
Invalidate depth resources when some block above this one has changed.
const MachineBasicBlock * Pred
Trace predecessor, or NULL for the first block in the trace.
unsigned InstrHeight
Accumulated number of instructions in the trace below this block.
SmallVector< LiveInReg, 4 > LiveIns
Live-in registers.
const MachineBasicBlock * Succ
Trace successor, or NULL for the last block in the trace.
bool hasValidDepth() const
Returns true if the depth resources have been computed from the trace above this block.
bool isUsefulDominator(const TraceBlockInfo &TBI) const
Assuming that this is a dominator of TBI, determine if it contains useful instruction depths.
void invalidateHeight()
Invalidate height resources when a block below this one has changed.
unsigned Head
The block number of the head of the trace. (When hasValidDepth()).
bool HasValidInstrDepths
Instruction depths have been computed. This implies hasValidDepth().
bool hasValidHeight() const
Returns true if the height resources have been computed from the trace below this block.
unsigned Tail
The block number of the tail of the trace. (When hasValidHeight()).
bool HasValidInstrHeights
Instruction heights have been computed. This implies hasValidHeight().
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition PassManager.h:69