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