LLVM  8.0.1
PassInstrumentation.h
Go to the documentation of this file.
1 //===- llvm/IR/PassInstrumentation.h ----------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 ///
11 /// This file defines the Pass Instrumentation classes that provide
12 /// instrumentation points into the pass execution by PassManager.
13 ///
14 /// There are two main classes:
15 /// - PassInstrumentation provides a set of instrumentation points for
16 /// pass managers to call on.
17 ///
18 /// - PassInstrumentationCallbacks registers callbacks and provides access
19 /// to them for PassInstrumentation.
20 ///
21 /// PassInstrumentation object is being used as a result of
22 /// PassInstrumentationAnalysis (so it is intended to be easily copyable).
23 ///
24 /// Intended scheme of use for Pass Instrumentation is as follows:
25 /// - register instrumentation callbacks in PassInstrumentationCallbacks
26 /// instance. PassBuilder provides helper for that.
27 ///
28 /// - register PassInstrumentationAnalysis with all the PassManagers.
29 /// PassBuilder handles that automatically when registering analyses.
30 ///
31 /// - Pass Manager requests PassInstrumentationAnalysis from analysis manager
32 /// and gets PassInstrumentation as its result.
33 ///
34 /// - Pass Manager invokes PassInstrumentation entry points appropriately,
35 /// passing StringRef identification ("name") of the pass currently being
36 /// executed and IRUnit it works on. There can be different schemes of
37 /// providing names in future, currently it is just a name() of the pass.
38 ///
39 /// - PassInstrumentation wraps address of IRUnit into llvm::Any and passes
40 /// control to all the registered callbacks. Note that we specifically wrap
41 /// 'const IRUnitT*' so as to avoid any accidental changes to IR in
42 /// instrumenting callbacks.
43 ///
44 /// - Some instrumentation points (BeforePass) allow to control execution
45 /// of a pass. For those callbacks returning false means pass will not be
46 /// executed.
47 ///
48 /// TODO: currently there is no way for a pass to opt-out of execution control
49 /// (e.g. become unskippable). PassManager is the only entity that determines
50 /// how pass instrumentation affects pass execution.
51 ///
52 //===----------------------------------------------------------------------===//
53 
54 #ifndef LLVM_IR_PASSINSTRUMENTATION_H
55 #define LLVM_IR_PASSINSTRUMENTATION_H
56 
57 #include "llvm/ADT/Any.h"
59 #include "llvm/ADT/SmallVector.h"
60 #include "llvm/Support/TypeName.h"
61 #include <type_traits>
62 
63 namespace llvm {
64 
65 class PreservedAnalyses;
66 
67 /// This class manages callbacks registration, as well as provides a way for
68 /// PassInstrumentation to pass control to the registered callbacks.
70 public:
71  // Before/After callbacks accept IRUnits whenever appropriate, so they need
72  // to take them as constant pointers, wrapped with llvm::Any.
73  // For the case when IRUnit has been invalidated there is a different
74  // callback to use - AfterPassInvalidated.
75  // TODO: currently AfterPassInvalidated does not accept IRUnit, since passing
76  // already invalidated IRUnit is unsafe. There are ways to handle invalidated IRUnits
77  // in a safe way, and we might pursue that as soon as there is a useful instrumentation
78  // that needs it.
80  using AfterPassFunc = void(StringRef, Any);
84 
85 public:
87 
88  /// Copying PassInstrumentationCallbacks is not intended.
90  void operator=(const PassInstrumentationCallbacks &) = delete;
91 
92  template <typename CallableT> void registerBeforePassCallback(CallableT C) {
93  BeforePassCallbacks.emplace_back(std::move(C));
94  }
95 
96  template <typename CallableT> void registerAfterPassCallback(CallableT C) {
97  AfterPassCallbacks.emplace_back(std::move(C));
98  }
99 
100  template <typename CallableT>
102  AfterPassInvalidatedCallbacks.emplace_back(std::move(C));
103  }
104 
105  template <typename CallableT>
107  BeforeAnalysisCallbacks.emplace_back(std::move(C));
108  }
109 
110  template <typename CallableT>
112  AfterAnalysisCallbacks.emplace_back(std::move(C));
113  }
114 
115 private:
116  friend class PassInstrumentation;
117 
121  AfterPassInvalidatedCallbacks;
123  BeforeAnalysisCallbacks;
125  AfterAnalysisCallbacks;
126 };
127 
128 /// This class provides instrumentation entry points for the Pass Manager,
129 /// doing calls to callbacks registered in PassInstrumentationCallbacks.
131  PassInstrumentationCallbacks *Callbacks;
132 
133 public:
134  /// Callbacks object is not owned by PassInstrumentation, its life-time
135  /// should at least match the life-time of corresponding
136  /// PassInstrumentationAnalysis (which usually is till the end of current
137  /// compilation).
139  : Callbacks(CB) {}
140 
141  /// BeforePass instrumentation point - takes \p Pass instance to be executed
142  /// and constant reference to IR it operates on. \Returns true if pass is
143  /// allowed to be executed.
144  template <typename IRUnitT, typename PassT>
145  bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const {
146  if (!Callbacks)
147  return true;
148 
149  bool ShouldRun = true;
150  for (auto &C : Callbacks->BeforePassCallbacks)
151  ShouldRun &= C(Pass.name(), llvm::Any(&IR));
152  return ShouldRun;
153  }
154 
155  /// AfterPass instrumentation point - takes \p Pass instance that has
156  /// just been executed and constant reference to \p IR it operates on.
157  /// \p IR is guaranteed to be valid at this point.
158  template <typename IRUnitT, typename PassT>
159  void runAfterPass(const PassT &Pass, const IRUnitT &IR) const {
160  if (Callbacks)
161  for (auto &C : Callbacks->AfterPassCallbacks)
162  C(Pass.name(), llvm::Any(&IR));
163  }
164 
165  /// AfterPassInvalidated instrumentation point - takes \p Pass instance
166  /// that has just been executed. For use when IR has been invalidated
167  /// by \p Pass execution.
168  template <typename IRUnitT, typename PassT>
169  void runAfterPassInvalidated(const PassT &Pass) const {
170  if (Callbacks)
171  for (auto &C : Callbacks->AfterPassInvalidatedCallbacks)
172  C(Pass.name());
173  }
174 
175  /// BeforeAnalysis instrumentation point - takes \p Analysis instance
176  /// to be executed and constant reference to IR it operates on.
177  template <typename IRUnitT, typename PassT>
178  void runBeforeAnalysis(const PassT &Analysis, const IRUnitT &IR) const {
179  if (Callbacks)
180  for (auto &C : Callbacks->BeforeAnalysisCallbacks)
181  C(Analysis.name(), llvm::Any(&IR));
182  }
183 
184  /// AfterAnalysis instrumentation point - takes \p Analysis instance
185  /// that has just been executed and constant reference to IR it operated on.
186  template <typename IRUnitT, typename PassT>
187  void runAfterAnalysis(const PassT &Analysis, const IRUnitT &IR) const {
188  if (Callbacks)
189  for (auto &C : Callbacks->AfterAnalysisCallbacks)
190  C(Analysis.name(), llvm::Any(&IR));
191  }
192 
193  /// Handle invalidation from the pass manager when PassInstrumentation
194  /// is used as the result of PassInstrumentationAnalysis.
195  ///
196  /// On attempt to invalidate just return false. There is nothing to become
197  /// invalid here.
198  template <typename IRUnitT, typename... ExtraArgsT>
199  bool invalidate(IRUnitT &, const class llvm::PreservedAnalyses &,
200  ExtraArgsT...) {
201  return false;
202  }
203 };
204 
205 } // namespace llvm
206 
207 #endif
Pass interface - Implemented by all &#39;passes&#39;.
Definition: Pass.h:81
uint64_t CallInst * C
Definition: Any.h:27
This class represents lattice values for constants.
Definition: AllocatorList.h:24
void operator=(const PassInstrumentationCallbacks &)=delete
PassInstrumentation(PassInstrumentationCallbacks *CB=nullptr)
Callbacks object is not owned by PassInstrumentation, its life-time should at least match the life-ti...
bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const
BeforePass instrumentation point - takes Pass instance to be executed and constant reference to IR it...
bool invalidate(IRUnitT &, const class llvm::PreservedAnalyses &, ExtraArgsT...)
Handle invalidation from the pass manager when PassInstrumentation is used as the result of PassInstr...
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:154
void runAfterPass(const PassT &Pass, const IRUnitT &IR) const
AfterPass instrumentation point - takes Pass instance that has just been executed and constant refere...
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
void runAfterPassInvalidated(const PassT &Pass) const
AfterPassInvalidated instrumentation point - takes Pass instance that has just been executed...
void registerAfterPassInvalidatedCallback(CallableT C)
block Block Frequency Analysis
void emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:652
void runBeforeAnalysis(const PassT &Analysis, const IRUnitT &IR) const
BeforeAnalysis instrumentation point - takes Analysis instance to be executed and constant reference ...
This file provides a collection of function (or more generally, callable) type erasure utilities supp...
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
This class provides instrumentation entry points for the Pass Manager, doing calls to callbacks regis...
Statically lint checks LLVM IR
Definition: Lint.cpp:193
void runAfterAnalysis(const PassT &Analysis, const IRUnitT &IR) const
AfterAnalysis instrumentation point - takes Analysis instance that has just been executed and constan...