MLIR 24.0.0git
Remarks.cpp
Go to the documentation of this file.
1//===- Remarks.cpp - C Interface for the MLIR Remark Engine ---------------===//
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#include "mlir-c/Remarks.h"
10#include "mlir/CAPI/IR.h"
11#include "mlir/CAPI/Remarks.h"
12#include "mlir/CAPI/Support.h"
13#include "mlir/CAPI/Utils.h"
14#include "mlir/IR/MLIRContext.h"
15#include "mlir/IR/Remarks.h"
17#include "llvm/Remarks/RemarkFormat.h"
18#include "llvm/Support/ErrorHandling.h"
19
20#include <cassert>
21#include <memory>
22
23using namespace mlir;
25
26//===----------------------------------------------------------------------===//
27// Helpers
28//===----------------------------------------------------------------------===//
29
30namespace {
31/// A streamer forwarding every reported remark to a C callback.
32class CallbackRemarkStreamer : public remark::detail::MLIRRemarkStreamerBase {
33public:
34 CallbackRemarkStreamer(MlirRemarkCallback callback, void *userData,
35 void (*deleteUserData)(void *))
36 : callback(callback), userData(userData), deleteUserData(deleteUserData) {
37 }
38
39 ~CallbackRemarkStreamer() override {
40 if (deleteUserData)
41 deleteUserData(userData);
42 }
43
44 void streamOptimizationRemark(const Remark &remark) override {
45 callback(wrap(&remark), userData);
46 }
47
48private:
49 MlirRemarkCallback callback;
50 void *userData;
51 void (*deleteUserData)(void *);
52};
53} // namespace
54
55/// Every filter reaches the engine as a (possibly empty) string, as with
56/// mlir-opt's options: a kind is reported when its own filter or `all` matches.
59 unwrap(categories.all).str(), unwrap(categories.passed).str(),
60 unwrap(categories.missed).str(), unwrap(categories.analysis).str(),
61 unwrap(categories.failed).str()};
62}
63
64static std::unique_ptr<remark::detail::RemarkEmittingPolicyBase>
66 switch (policy) {
68 return std::make_unique<remark::RemarkEmittingPolicyAll>();
70 return std::make_unique<remark::RemarkEmittingPolicyFinal>();
71 }
72 llvm_unreachable("unknown remark policy");
73}
74
75static llvm::remarks::Format unwrap(MlirRemarkFileFormat format) {
76 switch (format) {
78 return llvm::remarks::Format::YAML;
80 return llvm::remarks::Format::Bitstream;
81 }
82 llvm_unreachable("unknown remark file format");
83}
84
100
101//===----------------------------------------------------------------------===//
102// Enabling and finalizing
103//===----------------------------------------------------------------------===//
104
106 MlirContext context, MlirRemarkCategories categories,
107 MlirRemarkPolicy policy, bool printAsEmitRemarks) {
108 MLIRContext *ctx = unwrap(context);
109 if (ctx->getRemarkEngine())
112 *ctx, /*streamer=*/nullptr, createPolicy(policy), unwrap(categories),
113 printAsEmitRemarks));
114}
115
117 MlirContext context, MlirRemarkCategories categories,
119 bool printAsEmitRemarks) {
120 MLIRContext *ctx = unwrap(context);
121 if (ctx->getRemarkEngine())
124 *ctx, unwrap(path), unwrap(format), createPolicy(policy),
125 unwrap(categories), printAsEmitRemarks));
126}
127
129 MlirContext context, MlirRemarkCategories categories,
130 MlirRemarkPolicy policy, MlirRemarkCallback callback, void *userData,
131 void (*deleteUserData)(void *), bool printAsEmitRemarks) {
132 assert(callback && "unexpected null remark callback");
133 MLIRContext *ctx = unwrap(context);
134 if (ctx->getRemarkEngine()) {
135 // The caller handed over `userData`; release it as on success.
136 if (deleteUserData)
137 deleteUserData(userData);
139 }
141 *ctx,
142 std::make_unique<CallbackRemarkStreamer>(callback, userData,
143 deleteUserData),
144 createPolicy(policy), unwrap(categories), printAsEmitRemarks));
145}
146
147void mlirContextFinalizeOptimizationRemarks(MlirContext context) {
148 // The engine destructor reports the postponed remarks, then destroys the
149 // streamer.
150 unwrap(context)->setRemarkEngine(nullptr);
151}
152
153bool mlirContextHasRemarkEngine(MlirContext context) {
154 return unwrap(context)->getRemarkEngine() != nullptr;
155}
156
157//===----------------------------------------------------------------------===//
158// Remark accessors
159//===----------------------------------------------------------------------===//
160
164
168
172
174 return wrap(unwrap(remark)->getCombinedCategoryName());
175}
176
180
182 return wrap(unwrap(remark)->getLocation());
183}
184
186 return unwrap(remark)->getId().getValue();
187}
188
190 return static_cast<intptr_t>(unwrap(remark)->getArgs().size());
191}
192
194 ArrayRef<Remark::Arg> args = unwrap(remark)->getArgs();
195 assert(pos >= 0 && static_cast<size_t>(pos) < args.size() &&
196 "remark argument index out of range");
197 return wrap(llvm::StringRef(args[pos].key));
198}
199
201 ArrayRef<Remark::Arg> args = unwrap(remark)->getArgs();
202 assert(pos >= 0 && static_cast<size_t>(pos) < args.size() &&
203 "remark argument index out of range");
204 return wrap(llvm::StringRef(args[pos].val));
205}
206
208 void *userData) {
209 detail::CallbackOstream stream(callback, userData);
210 unwrap(remark)->print(stream);
211}
212
213//===----------------------------------------------------------------------===//
214// Emission
215//===----------------------------------------------------------------------===//
216
218 MlirLocation location, MlirRemarkKind kind, MlirStringRef remarkName,
219 MlirStringRef categoryName, MlirStringRef subCategoryName,
220 MlirStringRef functionName, MlirStringRef message, intptr_t numArgs,
221 const MlirStringRef *argKeys, const MlirStringRef *argValues) {
222 assert((numArgs == 0 || (argKeys && argValues)) &&
223 "remark arguments require both keys and values");
224 Location loc = unwrap(location);
226 .category(unwrap(categoryName))
227 .subCategory(unwrap(subCategoryName))
228 .function(unwrap(functionName));
230 switch (kind) {
232 return false;
234 inFlight = remark::passed(loc, opts);
235 break;
237 inFlight = remark::missed(loc, opts);
238 break;
240 inFlight = remark::failed(loc, opts);
241 break;
243 inFlight = remark::analysis(loc, opts);
244 break;
245 }
246 if (!inFlight)
247 return false;
248 if (message.length != 0)
249 inFlight << unwrap(message);
250 for (intptr_t i = 0; i < numArgs; ++i)
251 inFlight << Remark::Arg(unwrap(argKeys[i]), unwrap(argValues[i]));
252 // The remark is reported when `inFlight` goes out of scope.
253 return true;
254}
static MlirRemarkKind wrap(remark::RemarkKind kind)
Definition Remarks.cpp:85
intptr_t mlirRemarkGetNumArgs(MlirRemark remark)
Returns the number of key/value arguments attached to the remark.
Definition Remarks.cpp:189
MlirStringRef mlirRemarkGetRemarkName(MlirRemark remark)
Returns the name identifying the remark.
Definition Remarks.cpp:165
void mlirContextFinalizeOptimizationRemarks(MlirContext context)
Finalizes and removes the remark engine of the context: postponed remarks are reported,...
Definition Remarks.cpp:147
MlirLogicalResult mlirContextEnableOptimizationRemarks(MlirContext context, MlirRemarkCategories categories, MlirRemarkPolicy policy, bool printAsEmitRemarks)
Enables the remark engine on the context without a streamer; when printAsEmitRemarks is set,...
Definition Remarks.cpp:105
MlirStringRef mlirRemarkGetFullCategoryName(MlirRemark remark)
Returns the combined category:subcategory name of the remark.
Definition Remarks.cpp:173
void mlirRemarkPrint(MlirRemark remark, MlirStringCallback callback, void *userData)
Prints the remark in its textual form, [Kind] name | Category:... | / Function=......
Definition Remarks.cpp:207
uint64_t mlirRemarkGetId(MlirRemark remark)
Returns the unique id of the remark within its engine (0 when unset).
Definition Remarks.cpp:185
bool mlirContextHasRemarkEngine(MlirContext context)
Returns whether the context has a remark engine enabled.
Definition Remarks.cpp:153
MlirStringRef mlirRemarkGetCategoryName(MlirRemark remark)
Returns the category of the remark (the subject of the filters).
Definition Remarks.cpp:169
MlirStringRef mlirRemarkGetArgValue(MlirRemark remark, intptr_t pos)
Returns the value of the pos-th argument of the remark.
Definition Remarks.cpp:200
MlirStringRef mlirRemarkGetFunctionName(MlirRemark remark)
Returns the name of the function the remark refers to.
Definition Remarks.cpp:177
static std::unique_ptr< remark::detail::RemarkEmittingPolicyBase > createPolicy(MlirRemarkPolicy policy)
Definition Remarks.cpp:65
MlirRemarkKind mlirRemarkGetKind(MlirRemark remark)
Returns the kind of the remark.
Definition Remarks.cpp:161
MlirLogicalResult mlirContextEnableOptimizationRemarksToFile(MlirContext context, MlirRemarkCategories categories, MlirRemarkPolicy policy, MlirRemarkFileFormat format, MlirStringRef path, bool printAsEmitRemarks)
Enables the remark engine on the context, streaming the reported remarks to the file at path in forma...
Definition Remarks.cpp:116
MlirLogicalResult mlirContextEnableOptimizationRemarksWithCallback(MlirContext context, MlirRemarkCategories categories, MlirRemarkPolicy policy, MlirRemarkCallback callback, void *userData, void(*deleteUserData)(void *), bool printAsEmitRemarks)
Enables the remark engine on the context, delivering every reported remark to callback.
Definition Remarks.cpp:128
MlirStringRef mlirRemarkGetArgKey(MlirRemark remark, intptr_t pos)
Returns the key of the pos-th argument of the remark.
Definition Remarks.cpp:193
MlirLocation mlirRemarkGetLocation(MlirRemark remark)
Returns the location of the remark.
Definition Remarks.cpp:181
bool mlirEmitOptimizationRemark(MlirLocation location, MlirRemarkKind kind, MlirStringRef remarkName, MlirStringRef categoryName, MlirStringRef subCategoryName, MlirStringRef functionName, MlirStringRef message, intptr_t numArgs, const MlirStringRef *argKeys, const MlirStringRef *argValues)
Emits a remark of kind at location through the remark engine of the location's context.
Definition Remarks.cpp:217
static remark::RemarkCategories unwrap(MlirRemarkCategories categories)
Every filter reaches the engine as a (possibly empty) string, as with mlir-opt's options: a kind is r...
Definition Remarks.cpp:57
static remark::RemarkKind getRemarkKind(llvm::DiagnosticKind kind)
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:64
remark::detail::RemarkEngine * getRemarkEngine()
Returns the remark engine for this context, or nullptr if none has been set.
A simple raw ostream subclass that forwards write_impl calls to the user-supplied callback together w...
Definition Utils.h:30
A wrapper for linking remarks by query - searches the engine's registry at stream time and links to a...
Definition Remarks.h:402
Base class for MLIR remark streamers that is used to stream optimization remarks to the underlying re...
Definition Remarks.h:452
MlirRemarkFileFormat
The serialization format of a remark output file.
Definition Remarks.h:62
@ MlirRemarkFileFormatBitstream
Definition Remarks.h:64
@ MlirRemarkFileFormatYAML
Definition Remarks.h:63
MlirRemarkPolicy
The emitting policy of the remark engine.
Definition Remarks.h:52
@ MlirRemarkPolicyFinal
Postpone remarks and report the final set when the engine is finalized, grouping related remarks unde...
Definition Remarks.h:57
@ MlirRemarkPolicyAll
Report every remark as it is emitted.
Definition Remarks.h:54
void(* MlirRemarkCallback)(MlirRemark remark, void *userData)
Callback receiving every remark the engine reports.
Definition Remarks.h:82
MlirRemarkKind
The outcome a remark describes (see mlir::remark::RemarkKind).
Definition Remarks.h:38
@ MlirRemarkKindFailure
The optimization was attempted but failed.
Definition Remarks.h:45
@ MlirRemarkKindAnalysis
Informational context without a pass/fail outcome.
Definition Remarks.h:47
@ MlirRemarkKindMissed
A profitable optimization opportunity was found but not applied.
Definition Remarks.h:43
@ MlirRemarkKindUnknown
Definition Remarks.h:39
@ MlirRemarkKindPassed
An optimization was applied.
Definition Remarks.h:41
static MlirLogicalResult mlirLogicalResultFailure(void)
Creates a logical result representing a failure.
Definition Support.h:143
void(* MlirStringCallback)(MlirStringRef, void *)
A callback for returning string references.
Definition Support.h:110
detail::InFlightRemark failed(Location loc, RemarkOpts opts)
Report an optimization remark that failed.
Definition Remarks.h:734
detail::InFlightRemark missed(Location loc, RemarkOpts opts)
Report an optimization remark that was missed.
Definition Remarks.h:728
detail::InFlightRemark analysis(Location loc, RemarkOpts opts)
Report an optimization analysis remark.
Definition Remarks.h:740
LogicalResult enableOptimizationRemarks(MLIRContext &ctx, std::unique_ptr< remark::detail::MLIRRemarkStreamerBase > streamer, std::unique_ptr< remark::detail::RemarkEmittingPolicyBase > remarkEmittingPolicy, const remark::RemarkCategories &cats, bool printAsEmitRemarks=false)
Setup remarks for the context.
detail::InFlightRemark passed(Location loc, RemarkOpts opts)
Report an optimization remark that was passed.
Definition Remarks.h:723
LogicalResult enableOptimizationRemarksWithLLVMStreamer(MLIRContext &ctx, StringRef filePath, llvm::remarks::Format fmt, std::unique_ptr< detail::RemarkEmittingPolicyBase > remarkEmittingPolicy, const RemarkCategories &cat, bool printAsEmitRemarks=false)
Enable optimization remarks to a file with the given path and format.
RemarkKind
Categories describe the outcome of an transformation, not the mechanics of emitting/serializing remar...
Definition Remarks.h:70
@ RemarkPassed
An optimization was applied.
Definition Remarks.h:74
@ RemarkAnalysis
Informational context (e.g., analysis numbers) without a pass/fail outcome.
Definition Remarks.h:85
@ RemarkMissed
A profitable optimization opportunity was found but not applied.
Definition Remarks.h:77
@ RemarkFailure
The compiler attempted the optimization but failed (e.g., legality checks, or better opportunites).
Definition Remarks.h:81
Include the generated interface declarations.
A logical result value, essentially a boolean with named states.
Definition Support.h:121
Regular expressions (llvm::Regex syntax, anchored by the engine) selecting the remark categories to r...
Definition Remarks.h:72
MlirStringRef missed
Definition Remarks.h:75
MlirStringRef all
Definition Remarks.h:73
MlirStringRef analysis
Definition Remarks.h:76
MlirStringRef failed
Definition Remarks.h:77
MlirStringRef passed
Definition Remarks.h:74
An opaque reference to a remark.
Definition Remarks.h:32
A pointer to a sized fragment of a string, not necessarily null-terminated.
Definition Support.h:78
size_t length
Length of the fragment.
Definition Support.h:80
Define an the set of categories to accept.
Definition Remarks.h:64
Options to create a Remark.
Definition Remarks.h:95
RemarkOpts function(StringRef v) const
Return a copy with the function name set.
Definition Remarks.h:124
RemarkOpts subCategory(StringRef v) const
Return a copy with the subcategory set.
Definition Remarks.h:118
RemarkOpts category(StringRef v) const
Return a copy with the category set.
Definition Remarks.h:112
static RemarkOpts name(StringRef n)
Definition Remarks.h:105