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