1 | //===- 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 | |
9 | #ifndef MLIR_PASS_PASSINSTRUMENTATION_H_ |
10 | #define MLIR_PASS_PASSINSTRUMENTATION_H_ |
11 | |
12 | #include "mlir/Support/LLVM.h" |
13 | #include "mlir/Support/TypeID.h" |
14 | #include <optional> |
15 | |
16 | namespace mlir { |
17 | class OperationName; |
18 | class Operation; |
19 | class Pass; |
20 | |
21 | namespace detail { |
22 | struct PassInstrumentorImpl; |
23 | } // namespace detail |
24 | |
25 | /// PassInstrumentation provides several entry points into the pass manager |
26 | /// infrastructure. Instrumentations should be added directly to a PassManager |
27 | /// before running a pipeline. |
28 | class PassInstrumentation { |
29 | public: |
30 | /// This struct represents information related to the parent pass of pipeline. |
31 | /// It includes information that allows for effectively linking pipelines that |
32 | /// run on different threads. |
33 | struct PipelineParentInfo { |
34 | /// The thread of the parent pass that the current pipeline was spawned |
35 | /// from. Note: This is acquired from llvm::get_threadid(). |
36 | uint64_t parentThreadID; |
37 | |
38 | /// The pass that spawned this pipeline. |
39 | Pass *parentPass; |
40 | }; |
41 | |
42 | virtual ~PassInstrumentation() = 0; |
43 | |
44 | /// A callback to run before a pass pipeline is executed. This function takes |
45 | /// the name of the operation type being operated on, or std::nullopt if the |
46 | /// pipeline is op-agnostic, and information related to the parent that |
47 | /// spawned this pipeline. |
48 | virtual void runBeforePipeline(std::optional<OperationName> name, |
49 | const PipelineParentInfo &parentInfo); |
50 | |
51 | /// A callback to run after a pass pipeline has executed. This function takes |
52 | /// the name of the operation type being operated on, or std::nullopt if the |
53 | /// pipeline is op-agnostic, and information related to the parent that |
54 | /// spawned this pipeline. |
55 | virtual void runAfterPipeline(std::optional<OperationName> name, |
56 | const PipelineParentInfo &parentInfo); |
57 | |
58 | /// A callback to run before a pass is executed. This function takes a pointer |
59 | /// to the pass to be executed, as well as the current operation being |
60 | /// operated on. |
61 | virtual void runBeforePass(Pass *pass, Operation *op) {} |
62 | |
63 | /// A callback to run after a pass is successfully executed. This function |
64 | /// takes a pointer to the pass to be executed, as well as the current |
65 | /// operation being operated on. |
66 | virtual void runAfterPass(Pass *pass, Operation *op) {} |
67 | |
68 | /// A callback to run when a pass execution fails. This function takes a |
69 | /// pointer to the pass that was being executed, as well as the current |
70 | /// operation being operated on. Note that the operation may be in an invalid |
71 | /// state. |
72 | virtual void runAfterPassFailed(Pass *pass, Operation *op) {} |
73 | |
74 | /// A callback to run before an analysis is computed. This function takes the |
75 | /// name of the analysis to be computed, its TypeID, as well as the |
76 | /// current operation being analyzed. |
77 | virtual void runBeforeAnalysis(StringRef name, TypeID id, Operation *op) {} |
78 | |
79 | /// A callback to run before an analysis is computed. This function takes the |
80 | /// name of the analysis that was computed, its TypeID, as well as the |
81 | /// current operation being analyzed. |
82 | virtual void runAfterAnalysis(StringRef name, TypeID id, Operation *op) {} |
83 | }; |
84 | |
85 | /// This class holds a collection of PassInstrumentation objects, and invokes |
86 | /// their respective call backs. |
87 | class PassInstrumentor { |
88 | public: |
89 | PassInstrumentor(); |
90 | PassInstrumentor(PassInstrumentor &&) = delete; |
91 | PassInstrumentor(const PassInstrumentor &) = delete; |
92 | ~PassInstrumentor(); |
93 | |
94 | /// See PassInstrumentation::runBeforePipeline for details. |
95 | void |
96 | runBeforePipeline(std::optional<OperationName> name, |
97 | const PassInstrumentation::PipelineParentInfo &parentInfo); |
98 | |
99 | /// See PassInstrumentation::runAfterPipeline for details. |
100 | void |
101 | runAfterPipeline(std::optional<OperationName> name, |
102 | const PassInstrumentation::PipelineParentInfo &parentInfo); |
103 | |
104 | /// See PassInstrumentation::runBeforePass for details. |
105 | void runBeforePass(Pass *pass, Operation *op); |
106 | |
107 | /// See PassInstrumentation::runAfterPass for details. |
108 | void runAfterPass(Pass *pass, Operation *op); |
109 | |
110 | /// See PassInstrumentation::runAfterPassFailed for details. |
111 | void runAfterPassFailed(Pass *pass, Operation *op); |
112 | |
113 | /// See PassInstrumentation::runBeforeAnalysis for details. |
114 | void runBeforeAnalysis(StringRef name, TypeID id, Operation *op); |
115 | |
116 | /// See PassInstrumentation::runAfterAnalysis for details. |
117 | void runAfterAnalysis(StringRef name, TypeID id, Operation *op); |
118 | |
119 | /// Add the given instrumentation to the collection. |
120 | void addInstrumentation(std::unique_ptr<PassInstrumentation> pi); |
121 | |
122 | private: |
123 | std::unique_ptr<detail::PassInstrumentorImpl> impl; |
124 | }; |
125 | |
126 | } // namespace mlir |
127 | |
128 | namespace llvm { |
129 | template <> |
130 | struct DenseMapInfo<mlir::PassInstrumentation::PipelineParentInfo> { |
131 | using T = mlir::PassInstrumentation::PipelineParentInfo; |
132 | using PairInfo = DenseMapInfo<std::pair<uint64_t, void *>>; |
133 | |
134 | static T getEmptyKey() { |
135 | auto pair = PairInfo::getEmptyKey(); |
136 | return {.parentThreadID: pair.first, .parentPass: reinterpret_cast<mlir::Pass *>(pair.second)}; |
137 | } |
138 | static T getTombstoneKey() { |
139 | auto pair = PairInfo::getTombstoneKey(); |
140 | return {.parentThreadID: pair.first, .parentPass: reinterpret_cast<mlir::Pass *>(pair.second)}; |
141 | } |
142 | static unsigned getHashValue(T val) { |
143 | return PairInfo::getHashValue(PairVal: {val.parentThreadID, val.parentPass}); |
144 | } |
145 | static bool isEqual(T lhs, T rhs) { |
146 | return lhs.parentThreadID == rhs.parentThreadID && |
147 | lhs.parentPass == rhs.parentPass; |
148 | } |
149 | }; |
150 | } // namespace llvm |
151 | |
152 | #endif // MLIR_PASS_PASSINSTRUMENTATION_H_ |
153 | |