MLIR 23.0.0git
Remarks.h
Go to the documentation of this file.
1//===- Remarks.h - MLIR Optimization Remark ----------------------*- 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// This file defines utilities for emitting optimization remarks.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef MLIR_IR_REMARKS_H
14#define MLIR_IR_REMARKS_H
15
16#include "llvm/ADT/StringExtras.h"
17#include "llvm/IR/DiagnosticInfo.h"
18#include "llvm/Remarks/Remark.h"
19#include "llvm/Support/FormatVariadic.h"
20#include "llvm/Support/Regex.h"
21
22#include "mlir/IR/Diagnostics.h"
23#include "mlir/IR/MLIRContext.h"
24#include "mlir/IR/Value.h"
25
26#include <atomic>
27
28namespace mlir::remark {
29
30//===----------------------------------------------------------------------===//
31// RemarkId - Unique identifier for linking related remarks
32//===----------------------------------------------------------------------===//
33
34/// A unique identifier for a remark, used to link related remarks together.
35/// An invalid/empty ID has value 0.
36class RemarkId {
37public:
38 RemarkId() : id(0) {}
39 explicit RemarkId(uint64_t id) : id(id) {}
40
41 /// Check if this is a valid (non-zero) ID.
42 explicit operator bool() const { return id != 0; }
43
44 /// Get the raw ID value.
45 uint64_t getValue() const { return id; }
46
47 bool operator==(const RemarkId &other) const { return id == other.id; }
48 bool operator!=(const RemarkId &other) const { return id != other.id; }
49
50 /// Print the ID.
51 void print(llvm::raw_ostream &os) const { os << "remark-" << id; }
52
53private:
54 uint64_t id;
55};
56
57inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os, RemarkId id) {
58 id.print(os);
59 return os;
60}
61
62/// Define an the set of categories to accept. By default none are, the provided
63/// regex matches against the category names for each kind of remark.
65 std::optional<std::string> all, passed, missed, analysis, failed;
66};
67
68/// Categories describe the outcome of an transformation, not the mechanics of
69/// emitting/serializing remarks.
70enum class RemarkKind {
72
73 /// An optimization was applied.
75
76 /// A profitable optimization opportunity was found but not applied.
78
79 /// The compiler attempted the optimization but failed (e.g., legality
80 /// checks, or better opportunites).
82
83 /// Informational context (e.g., analysis numbers) without a pass/fail
84 /// outcome.
86};
87
88using namespace llvm;
89
90namespace detail {
91class InFlightRemark; // forward declaration
92} // namespace detail
93
94/// Options to create a Remark
95struct RemarkOpts {
96 StringRef remarkName; // Identifiable name
97 StringRef categoryName; // Category name (subject to regex filtering)
98 StringRef subCategoryName; // Subcategory name
99 StringRef functionName; // Function name if available
100
101 /// Link to a related remark by explicit ID.
103
104 // Construct RemarkOpts from a remark name.
105 static RemarkOpts name(StringRef n) {
106 RemarkOpts o;
107 o.remarkName = n;
108 return o;
109 }
110
111 /// Return a copy with the category set.
112 RemarkOpts category(StringRef v) const {
113 auto copy = *this;
114 copy.categoryName = v;
115 return copy;
116 }
117 /// Return a copy with the subcategory set.
118 RemarkOpts subCategory(StringRef v) const {
119 auto copy = *this;
120 copy.subCategoryName = v;
121 return copy;
122 }
123 /// Return a copy with the function name set.
124 RemarkOpts function(StringRef v) const {
125 auto copy = *this;
126 copy.functionName = v;
127 return copy;
128 }
129
130 /// Link this remark to a previously emitted remark by explicit ID.
132 auto copy = *this;
133 copy.relatedId = id;
134 return copy;
135 }
136
137 /// Link this remark to a related remark that is still in flight.
138 /// Extracts the ID from the InFlightRemark.
139 inline RemarkOpts relatedTo(const detail::InFlightRemark &r) const;
140};
141
142} // namespace mlir::remark
143
144namespace mlir::remark::detail {
145//===----------------------------------------------------------------------===//
146// Remark Base Class
147//===----------------------------------------------------------------------===//
148class Remark {
149
150public:
152 RemarkOpts opts)
154 categoryName(opts.categoryName.str()),
156 remarkName(opts.remarkName.str()) {
157 if (!categoryName.empty() && !subCategoryName.empty()) {
158 (llvm::Twine(categoryName) + ":" + subCategoryName)
159 .toVector(fullCategoryName);
160 }
161 // Explicit ID linking from opts.
162 if (opts.relatedId)
164 }
165
166 // Remark argument that is a key-value pair that can be printed as machine
167 // parsable args. For Attribute arguments, the original attribute is also
168 // stored to allow custom streamers to handle them specially.
169 struct Arg {
170 std::string key;
171 std::string val;
172 /// Optional attribute storage for Attribute-based args. Allows streamers
173 /// to access the original attribute for custom handling.
174 std::optional<Attribute> attr;
175
176 Arg(llvm::StringRef m) : key("Remark"), val(m) {}
177 Arg(llvm::StringRef k, llvm::StringRef v) : key(k), val(v) {}
178 Arg(llvm::StringRef k, std::string v) : key(k), val(std::move(v)) {}
179 Arg(llvm::StringRef k, const char *v) : Arg(k, llvm::StringRef(v)) {}
180 Arg(llvm::StringRef k, Value v);
181 Arg(llvm::StringRef k, Type t);
182 Arg(llvm::StringRef k, Attribute a);
183 Arg(llvm::StringRef k, bool b) : key(k), val(b ? "true" : "false") {}
184
185 /// Check if this arg has an associated attribute.
186 bool hasAttribute() const { return attr.has_value(); }
187
188 /// Get the attribute if present.
189 Attribute getAttribute() const { return attr.value_or(Attribute()); }
190
191 // One constructor for all arithmetic types except bool.
192 template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T> &&
193 !std::is_same_v<T, bool>>>
194 Arg(llvm::StringRef k, T v) : key(k) {
195 if constexpr (std::is_floating_point_v<T>) {
196 llvm::raw_string_ostream os(val);
197 os << v;
198 } else if constexpr (std::is_signed_v<T>) {
199 val = llvm::itostr(static_cast<long long>(v));
200 } else {
201 val = llvm::utostr(static_cast<unsigned long long>(v));
202 }
203 }
204 };
205
206 void insert(llvm::StringRef s);
207 void insert(Arg a);
208
209 void print(llvm::raw_ostream &os, bool printLocation = false) const;
210
211 Location getLocation() const { return loc; }
212 /// Diagnostic -> Remark
213 llvm::remarks::Remark generateRemark() const;
214
215 StringRef getFunction() const {
216 if (!functionName.empty())
217 return functionName;
218 return "<unknown function>";
219 }
220
221 llvm::StringRef getCategoryName() const { return categoryName; }
222
223 llvm::StringRef getCombinedCategoryName() const {
224 if (categoryName.empty() && subCategoryName.empty())
225 return {};
226 if (subCategoryName.empty())
227 return categoryName;
228 if (categoryName.empty())
229 return subCategoryName;
230 return fullCategoryName;
231 }
232
233 StringRef getRemarkName() const {
234 if (remarkName.empty())
235 return "<unknown remark name>";
236 return remarkName;
237 }
238
239 std::string getMsg() const;
240
241 ArrayRef<Arg> getArgs() const { return args; }
242
243 llvm::remarks::Type getRemarkType() const;
244
245 //===--------------------------------------------------------------------===//
246 // Remark Linking Support
247 //===--------------------------------------------------------------------===//
248
249 /// Get this remark's unique ID (0 if not assigned).
250 RemarkId getId() const { return id; }
251
252 /// Set this remark's unique ID. Also adds it as an Arg for serialization.
253 void setId(RemarkId newId) {
254 id = newId;
255 if (id)
256 args.emplace_back("RemarkId", llvm::utostr(id.getValue()));
257 }
258
259 /// Get the list of related remark IDs.
261
262 /// Add a reference to a related remark. Also adds it as an Arg for
263 /// serialization.
264 void addRelatedRemark(RemarkId relatedId) {
265 if (relatedId) {
266 relatedRemarks.push_back(relatedId);
267 args.emplace_back("RelatedTo", llvm::utostr(relatedId.getValue()));
268 }
269 }
270
271 /// Check if this remark has any related remarks.
272 bool hasRelatedRemarks() const { return !relatedRemarks.empty(); }
273
274 /// Get the remark kind.
276
277 StringRef getRemarkTypeString() const;
278
279protected:
280 /// Keeps the MLIR diagnostic kind, which is used to determine the
281 /// diagnostic kind in the LLVM remark streamer.
283 /// Name of the covering function like interface.
284 /// Stored as std::string to ensure the Remark owns its data.
285 std::string functionName;
286
288 /// Category name e.g., "Unroll" or "UnrollAndJam".
289 /// Stored as std::string to ensure the Remark owns its data.
290 std::string categoryName;
291
292 /// Sub category name e.g., "Loop Optimizer".
293 /// Stored as std::string to ensure the Remark owns its data.
294 std::string subCategoryName;
295
296 /// Combined name for category and sub-category
298
299 /// Remark identifier.
300 /// Stored as std::string to ensure the Remark owns its data.
301 std::string remarkName;
302
303 /// Args collected via the streaming interface.
305
306 /// Unique ID for this remark (assigned by RemarkEngine).
308
309 /// IDs of related remarks (e.g., parent analysis that enabled this opt).
311
312private:
313 /// Convert the MLIR diagnostic severity to LLVM diagnostic severity.
314 static llvm::DiagnosticSeverity
315 makeLLVMSeverity(DiagnosticSeverity severity) {
316 switch (severity) {
318 return llvm::DiagnosticSeverity::DS_Note;
320 return llvm::DiagnosticSeverity::DS_Warning;
322 return llvm::DiagnosticSeverity::DS_Error;
324 return llvm::DiagnosticSeverity::DS_Remark;
325 }
326 llvm_unreachable("Unknown diagnostic severity");
327 }
328 /// Convert the MLIR remark kind to LLVM diagnostic kind.
329 static llvm::DiagnosticKind makeLLVMKind(RemarkKind remarkKind) {
330 switch (remarkKind) {
332 return llvm::DiagnosticKind::DK_Generic;
334 return llvm::DiagnosticKind::DK_OptimizationRemark;
336 return llvm::DiagnosticKind::DK_OptimizationRemarkMissed;
338 return llvm::DiagnosticKind::DK_OptimizationFailure;
340 return llvm::DiagnosticKind::DK_OptimizationRemarkAnalysis;
341 }
342 llvm_unreachable("Unknown diagnostic kind");
343 }
344};
345
346inline Remark &operator<<(Remark &r, StringRef s) {
347 r.insert(s);
348 return r;
349}
350inline Remark &&operator<<(Remark &&r, StringRef s) {
351 r.insert(s);
352 return std::move(r);
353}
354inline Remark &operator<<(Remark &r, const Remark::Arg &kv) {
355 r.insert(kv);
356 return r;
357}
358
359//===----------------------------------------------------------------------===//
360// Shorthand aliases for different kinds of remarks.
361//===----------------------------------------------------------------------===//
362
363template <RemarkKind K, DiagnosticSeverity S>
364class OptRemarkBase final : public Remark {
365public:
367 : Remark(K, S, loc, opts) {}
368};
369
372
375
378
381
382class RemarkEngine;
383
384//===----------------------------------------------------------------------===//
385// InFlightRemark
386//===----------------------------------------------------------------------===//
387
388/// Lazy text building for zero cost string formatting.
390 llvm::StringRef key;
391 std::function<std::string()> thunk;
392};
393
394/// A wrapper for linking remarks by query - searches the engine's registry
395/// at stream time and links to all matching remarks.
396
397/// InFlightRemark is a RAII class that holds a reference to a Remark
398/// instance and allows to build the remark using the << operator. The remark
399/// is emitted when the InFlightRemark instance is destroyed, which happens
400/// when the scope ends or when the InFlightRemark instance is moved.
401/// Similar to InFlightDiagnostic, but for remarks.
403public:
404 explicit InFlightRemark(std::unique_ptr<Remark> diag)
405 : remark(std::move(diag)) {}
406
407 InFlightRemark(RemarkEngine &eng, std::unique_ptr<Remark> diag)
408 : owner(&eng), remark(std::move(diag)) {}
409
410 InFlightRemark() = default; // empty ctor
411
413 if (remark)
414 *remark << Remark::Arg(l.key, l.thunk());
415 return *this;
416 }
417
418 // Generic path, but *not* for Lazy
419 template <typename T, typename = std::enable_if_t<
420 !std::is_same_v<std::decay_t<T>, LazyTextBuild>>>
422 if (remark)
423 *remark << std::forward<T>(arg);
424 return *this;
425 }
426
427 explicit operator bool() const { return remark != nullptr; }
428
429 /// Get this remark's unique ID (for linking from other remarks).
430 RemarkId getId() const { return remark ? remark->getId() : RemarkId(); }
431
433
438
439private:
440 RemarkEngine *owner{nullptr};
441 std::unique_ptr<Remark> remark;
442};
443
444//===----------------------------------------------------------------------===//
445// Pluggable Remark Utilities
446//===----------------------------------------------------------------------===//
447
448/// Base class for MLIR remark streamers that is used to stream
449/// optimization remarks to the underlying remark streamer. The derived classes
450/// should implement the `streamOptimizationRemark` method to provide the
451/// actual streaming implementation.
453public:
454 virtual ~MLIRRemarkStreamerBase() = default;
455 /// Stream an optimization remark to the underlying remark streamer. It is
456 /// called by the RemarkEngine to stream the optimization remarks.
457 ///
458 /// It must be overridden by the derived classes to provide
459 /// the actual streaming implementation.
460 virtual void streamOptimizationRemark(const Remark &remark) = 0;
461
462 virtual void finalize() {} // optional
463};
464
465using ReportFn = llvm::unique_function<void(const Remark &)>;
466
467/// Base class for MLIR remark emitting policies that is used to emit
468/// optimization remarks to the underlying remark streamer. The derived classes
469/// should implement the `reportRemark` method to provide the actual emitting
470/// implementation.
472protected:
474
475public:
477 virtual ~RemarkEmittingPolicyBase() = default;
478
479 void initialize(ReportFn fn) { reportImpl = std::move(fn); }
480
481 virtual void reportRemark(const Remark &remark) = 0;
482 virtual void finalize() = 0;
483
484 /// Find previously reported remarks matching the given criteria.
485 /// Default returns empty -- only policies that store remarks (like
486 /// PolicyFinal) override this to enable query-based linking.
489 std::optional<RemarkKind> kind = std::nullopt) const {
490 return {};
491 }
492};
493
494//===----------------------------------------------------------------------===//
495// Remark Engine (MLIR Context will own this class)
496//===----------------------------------------------------------------------===//
497
499private:
500 /// Regex that filters missed optimization remarks: only matching one are
501 /// reported.
502 std::optional<llvm::Regex> missFilter;
503 /// The category for passed optimization remarks.
504 std::optional<llvm::Regex> passedFilter;
505 /// The category for analysis remarks.
506 std::optional<llvm::Regex> analysisFilter;
507 /// The category for failed optimization remarks.
508 std::optional<llvm::Regex> failedFilter;
509 /// The MLIR remark streamer that will be used to emit the remarks.
510 std::unique_ptr<MLIRRemarkStreamerBase> remarkStreamer;
511 /// The MLIR remark policy that will be used to emit the remarks.
512 std::unique_ptr<RemarkEmittingPolicyBase> remarkEmittingPolicy;
513 /// When is enabled, engine also prints remarks as mlir::emitRemarks.
514 bool printAsEmitRemarks = false;
515 /// Atomic counter for generating unique remark IDs.
516 std::atomic<uint64_t> nextRemarkId{1};
517
518 /// Return true if missed optimization remarks are enabled, override
519 /// to provide different implementation.
520 bool isMissedOptRemarkEnabled(StringRef categoryName) const;
521
522 /// Return true if passed optimization remarks are enabled, override
523 /// to provide different implementation.
524 bool isPassedOptRemarkEnabled(StringRef categoryName) const;
525
526 /// Return true if analysis optimization remarks are enabled, override
527 /// to provide different implementation.
528 bool isAnalysisOptRemarkEnabled(StringRef categoryName) const;
529
530 /// Return true if analysis optimization remarks are enabled, override
531 /// to provide different implementation.
532 bool isFailedOptRemarkEnabled(StringRef categoryName) const;
533
534 /// Return true if any type of remarks are enabled for this pass.
535 bool isAnyRemarkEnabled(StringRef categoryName) const {
536 return isMissedOptRemarkEnabled(categoryName) ||
537 isPassedOptRemarkEnabled(categoryName) ||
538 isFailedOptRemarkEnabled(categoryName) ||
539 isAnalysisOptRemarkEnabled(categoryName);
540 }
541
542 /// Emit a remark using the given maker function, which should return
543 /// a Remark instance. The remark will be emitted using the main
544 /// remark streamer.
545 template <typename RemarkT>
546 InFlightRemark makeRemark(Location loc, RemarkOpts opts);
547
548 template <typename RemarkT>
549 InFlightRemark emitIfEnabled(Location loc, RemarkOpts opts,
550 bool (RemarkEngine::*isEnabled)(StringRef)
551 const);
552 /// Report a remark.
553 void reportImpl(const Remark &remark);
554
555public:
556 /// Default constructor is deleted, use the other constructor.
557 RemarkEngine() = delete;
558
559 /// Constructs Remark engine with optional category names. If a category
560 /// name is not provided, it is not enabled. The category names are used to
561 /// filter the remarks that are emitted.
562 RemarkEngine(bool printAsEmitRemarks, const RemarkCategories &cats);
563
564 /// Destructor that will close the output file and reset the
565 /// main remark streamer.
567
568 /// Setup the remark engine with the given output path and format.
569 LogicalResult
570 initialize(std::unique_ptr<MLIRRemarkStreamerBase> streamer,
571 std::unique_ptr<RemarkEmittingPolicyBase> remarkEmittingPolicy,
572 std::string *errMsg);
573
574 /// Get the remark emitting policy.
576 return remarkEmittingPolicy.get();
577 }
578
579 /// Generate a unique ID for a new remark.
581 return RemarkId(nextRemarkId.fetch_add(1, std::memory_order_relaxed));
582 }
583
584 //===--------------------------------------------------------------------===//
585 // Remark Linking - query previously emitted remarks
586 //===--------------------------------------------------------------------===//
587
588 /// Find all remarks matching the given criteria. Delegates to the
589 /// emitting policy. Only works with policies that store remarks
590 /// (e.g. RemarkEmittingPolicyFinal); returns empty for PolicyAll.
593 std::optional<RemarkKind> kind = std::nullopt) const;
594
595 /// Report a remark.
596 void report(const Remark &&remark);
597
598 /// Report a successful remark, this will create an InFlightRemark
599 /// that can be used to build the remark using the << operator.
601
602 /// Report a missed optimization remark
603 /// that can be used to build the remark using the << operator.
605
606 /// Report a failed optimization remark, this will create an InFlightRemark
607 /// that can be used to build the remark using the << operator.
609
610 /// Report an analysis remark, this will create an InFlightRemark
611 /// that can be used to build the remark using the << operator.
613};
614
615template <typename Fn, typename... Args>
616inline InFlightRemark withEngine(Fn fn, Location loc, Args &&...args) {
617 MLIRContext *ctx = loc->getContext();
618
619 RemarkEngine *enginePtr = ctx->getRemarkEngine();
620
621 if (LLVM_UNLIKELY(enginePtr))
622 return (enginePtr->*fn)(loc, std::forward<Args>(args)...);
623
624 return {};
625}
626
627} // namespace mlir::remark::detail
628
629// Deferred definition: needs InFlightRemark to be complete.
634
635namespace mlir::remark {
636
637//===----------------------------------------------------------------------===//
638// Remark Emitting Policies
639//===----------------------------------------------------------------------===//
640
641/// Policy that emits all remarks.
643public:
645
646 void reportRemark(const detail::Remark &remark) override {
647 assert(reportImpl && "reportImpl is not set");
649 }
650 void finalize() override {}
651};
652
653/// Policy that emits final remarks. Stores all remarks until finalize(),
654/// which enables query-based linking via findRemarks().
656private:
657 /// user can intercept them for custom processing via a registered callback,
658 /// otherwise they will be reported on engine destruction.
659 llvm::DenseSet<detail::Remark> postponedRemarks;
660
661public:
663
664 void reportRemark(const detail::Remark &remark) override {
665 postponedRemarks.erase(remark);
666 postponedRemarks.insert(remark);
667 }
668
669 /// Emits all stored remarks. Related remarks are printed as nested notes
670 /// under the remark that references them.
671 void finalize() override;
672};
673
674/// Create a Reason with llvm::formatv formatting.
675template <class... Ts>
676inline detail::LazyTextBuild reason(const char *fmt, Ts &&...ts) {
677 return {"Reason", [=] { return llvm::formatv(fmt, ts...).str(); }};
678}
679
680/// Create a Suggestion with llvm::formatv formatting.
681template <class... Ts>
682inline detail::LazyTextBuild suggest(const char *fmt, Ts &&...ts) {
683 return {"Suggestion", [=] { return llvm::formatv(fmt, ts...).str(); }};
684}
685
686/// Create a Remark with llvm::formatv formatting.
687template <class... Ts>
688inline detail::LazyTextBuild add(const char *fmt, Ts &&...ts) {
689 return {"Remark", [=] { return llvm::formatv(fmt, ts...).str(); }};
690}
691
692template <class V>
693inline detail::LazyTextBuild metric(StringRef key, V &&v) {
694 using DV = std::decay_t<V>;
695 return {key, [key, vv = DV(std::forward<V>(v))]() mutable {
696 // Reuse Arg's formatting logic and return just the value string.
697 return detail::Remark::Arg(key, std::move(vv)).val;
698 }};
699}
700
701//===----------------------------------------------------------------------===//
702// Emitters
703//===----------------------------------------------------------------------===//
704
705/// Report an optimization remark that was passed.
707 return withEngine(&detail::RemarkEngine::emitOptimizationRemark, loc, opts);
708}
709
710/// Report an optimization remark that was missed.
713 opts);
714}
715
716/// Report an optimization remark that failed.
719 opts);
720}
721
722/// Report an optimization analysis remark.
725 opts);
726}
727
728//===----------------------------------------------------------------------===//
729// Setup
730//===----------------------------------------------------------------------===//
731
732/// Setup remarks for the context. This function will enable the remark engine
733/// and set the streamer to be used for optimization remarks. The remark
734/// categories are used to filter the remarks that will be emitted by the
735/// remark engine. If a category is not specified, it will not be emitted. If
736/// `printAsEmitRemarks` is true, the remarks will be printed as
737/// mlir::emitRemarks. 'streamer' must inherit from MLIRRemarkStreamerBase and
738/// will be used to stream the remarks.
740 MLIRContext &ctx,
741 std::unique_ptr<remark::detail::MLIRRemarkStreamerBase> streamer,
742 std::unique_ptr<remark::detail::RemarkEmittingPolicyBase>
743 remarkEmittingPolicy,
744 const remark::RemarkCategories &cats, bool printAsEmitRemarks = false);
745
746} // namespace mlir::remark
747
748// DenseMapInfo specialization for Remark
749namespace llvm {
750template <>
751struct DenseMapInfo<mlir::remark::detail::Remark> {
752 static constexpr StringRef kEmptyKey = "<EMPTY_KEY>";
753 static constexpr StringRef kTombstoneKey = "<TOMBSTONE_KEY>";
754
755 /// Helper to provide a static dummy context for sentinel keys.
757 static mlir::MLIRContext dummyContext;
758 return &dummyContext;
759 }
760
761 /// Create an empty remark
768
769 /// Create a dead remark
776
777 /// Compute the hash value of the remark
778 static unsigned getHashValue(const mlir::remark::detail::Remark &remark) {
779 return llvm::hash_combine(
781 llvm::hash_value(remark.getRemarkName()),
782 llvm::hash_value(remark.getCombinedCategoryName()),
783 static_cast<unsigned>(remark.getRemarkKind()));
784 }
785
788 // Check for empty/tombstone keys first
789 if (lhs.getRemarkName() == kEmptyKey ||
790 lhs.getRemarkName() == kTombstoneKey ||
791 rhs.getRemarkName() == kEmptyKey ||
792 rhs.getRemarkName() == kTombstoneKey) {
793 return lhs.getRemarkName() == rhs.getRemarkName();
794 }
795
796 // For regular remarks, compare key identifying fields
797 return lhs.getLocation() == rhs.getLocation() &&
798 lhs.getRemarkName() == rhs.getRemarkName() &&
799 lhs.getCombinedCategoryName() == rhs.getCombinedCategoryName() &&
800 lhs.getRemarkKind() == rhs.getRemarkKind();
801 }
802};
803} // namespace llvm
804#endif // MLIR_IR_REMARKS_H
static void copy(Location loc, Value dst, Value src, Value size, OpBuilder &builder)
Copies the given number of bytes from src to dst pointers.
lhs
b
Return true if permutation is a valid permutation of the outer_dims_perm (case OuterOrInnerPerm::Oute...
if(!isCopyOut)
static std::string diag(const llvm::Value &value)
#define add(a, b)
Attributes are known-constant values of operations.
Definition Attributes.h:25
MLIRContext * getContext() const
Return the context this attribute belongs to.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
const void * getAsOpaquePointer() const
Methods for supporting PointerLikeTypeTraits.
Definition Location.h:103
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
remark::detail::RemarkEngine * getRemarkEngine()
Returns the remark engine for this context, or nullptr if none has been set.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
void reportRemark(const detail::Remark &remark) override
Definition Remarks.h:646
void finalize() override
Emits all stored remarks.
Definition Remarks.cpp:351
void reportRemark(const detail::Remark &remark) override
Definition Remarks.h:664
A unique identifier for a remark, used to link related remarks together.
Definition Remarks.h:36
bool operator!=(const RemarkId &other) const
Definition Remarks.h:48
void print(llvm::raw_ostream &os) const
Print the ID.
Definition Remarks.h:51
bool operator==(const RemarkId &other) const
Definition Remarks.h:47
uint64_t getValue() const
Get the raw ID value.
Definition Remarks.h:45
RemarkId(uint64_t id)
Definition Remarks.h:39
A wrapper for linking remarks by query - searches the engine's registry at stream time and links to a...
Definition Remarks.h:402
InFlightRemark(RemarkEngine &eng, std::unique_ptr< Remark > diag)
Definition Remarks.h:407
InFlightRemark(std::unique_ptr< Remark > diag)
Definition Remarks.h:404
InFlightRemark(const InFlightRemark &)=delete
InFlightRemark & operator<<(const LazyTextBuild &l)
Definition Remarks.h:412
RemarkId getId() const
Get this remark's unique ID (for linking from other remarks).
Definition Remarks.h:430
InFlightRemark(InFlightRemark &&)=default
InFlightRemark & operator=(InFlightRemark &&)=default
InFlightRemark & operator<<(T &&arg)
Definition Remarks.h:421
InFlightRemark & operator=(const InFlightRemark &)=delete
Base class for MLIR remark streamers that is used to stream optimization remarks to the underlying re...
Definition Remarks.h:452
virtual void streamOptimizationRemark(const Remark &remark)=0
Stream an optimization remark to the underlying remark streamer.
OptRemarkBase(Location loc, RemarkOpts opts)
Definition Remarks.h:366
Base class for MLIR remark emitting policies that is used to emit optimization remarks to the underly...
Definition Remarks.h:471
virtual void reportRemark(const Remark &remark)=0
virtual SmallVector< RemarkId > findRemarks(const RemarkOpts &opts, std::optional< RemarkKind > kind=std::nullopt) const
Find previously reported remarks matching the given criteria.
Definition Remarks.h:488
InFlightRemark emitOptimizationRemarkFailure(Location loc, RemarkOpts opts)
Report a failed optimization remark, this will create an InFlightRemark that can be used to build the...
Definition Remarks.cpp:220
void report(const Remark &&remark)
Report a remark.
Definition Remarks.cpp:247
RemarkId generateRemarkId()
Generate a unique ID for a new remark.
Definition Remarks.h:580
InFlightRemark emitOptimizationRemark(Location loc, RemarkOpts opts)
Report a successful remark, this will create an InFlightRemark that can be used to build the remark u...
Definition Remarks.cpp:208
RemarkEmittingPolicyBase * getRemarkEmittingPolicy() const
Get the remark emitting policy.
Definition Remarks.h:575
SmallVector< RemarkId > findRemarks(const RemarkOpts &opts, std::optional< RemarkKind > kind=std::nullopt) const
Find all remarks matching the given criteria.
LogicalResult initialize(std::unique_ptr< MLIRRemarkStreamerBase > streamer, std::unique_ptr< RemarkEmittingPolicyBase > remarkEmittingPolicy, std::string *errMsg)
Setup the remark engine with the given output path and format.
Definition Remarks.cpp:260
RemarkEngine()=delete
Default constructor is deleted, use the other constructor.
InFlightRemark emitOptimizationRemarkMiss(Location loc, RemarkOpts opts)
Report a missed optimization remark that can be used to build the remark using the << operator.
Definition Remarks.cpp:214
~RemarkEngine()
Destructor that will close the output file and reset the main remark streamer.
Definition Remarks.cpp:252
InFlightRemark emitOptimizationRemarkAnalysis(Location loc, RemarkOpts opts)
Report an analysis remark, this will create an InFlightRemark that can be used to build the remark us...
Definition Remarks.cpp:226
RemarkId id
Unique ID for this remark (assigned by RemarkEngine).
Definition Remarks.h:307
std::string functionName
Name of the covering function like interface.
Definition Remarks.h:285
bool hasRelatedRemarks() const
Check if this remark has any related remarks.
Definition Remarks.h:272
void print(llvm::raw_ostream &os, bool printLocation=false) const
Print the remark to the given output stream.
Definition Remarks.cpp:75
void setId(RemarkId newId)
Set this remark's unique ID. Also adds it as an Arg for serialization.
Definition Remarks.h:253
RemarkId getId() const
Get this remark's unique ID (0 if not assigned).
Definition Remarks.h:250
ArrayRef< Arg > getArgs() const
Definition Remarks.h:241
SmallVector< Arg, 4 > args
Args collected via the streaming interface.
Definition Remarks.h:304
llvm::StringRef getCategoryName() const
Definition Remarks.h:221
StringRef getFunction() const
Definition Remarks.h:215
Remark(RemarkKind remarkKind, DiagnosticSeverity severity, Location loc, RemarkOpts opts)
Definition Remarks.h:151
llvm::remarks::Type getRemarkType() const
Definition Remarks.cpp:122
StringRef getRemarkTypeString() const
Definition Remarks.cpp:106
std::string remarkName
Remark identifier.
Definition Remarks.h:301
Location getLocation() const
Definition Remarks.h:211
std::string subCategoryName
Sub category name e.g., "Loop Optimizer".
Definition Remarks.h:294
RemarkKind getRemarkKind() const
Get the remark kind.
Definition Remarks.h:275
llvm::StringRef getCombinedCategoryName() const
Definition Remarks.h:223
void addRelatedRemark(RemarkId relatedId)
Add a reference to a related remark.
Definition Remarks.h:264
RemarkKind remarkKind
Keeps the MLIR diagnostic kind, which is used to determine the diagnostic kind in the LLVM remark str...
Definition Remarks.h:282
StringRef getRemarkName() const
Definition Remarks.h:233
SmallString< 64 > fullCategoryName
Combined name for category and sub-category.
Definition Remarks.h:297
SmallVector< RemarkId > relatedRemarks
IDs of related remarks (e.g., parent analysis that enabled this opt).
Definition Remarks.h:310
ArrayRef< RemarkId > getRelatedRemarkIds() const
Get the list of related remark IDs.
Definition Remarks.h:260
void insert(llvm::StringRef s)
Definition Remarks.cpp:39
llvm::remarks::Remark generateRemark() const
Diagnostic -> Remark.
Definition Remarks.cpp:138
std::string categoryName
Category name e.g., "Unroll" or "UnrollAndJam".
Definition Remarks.h:290
std::string getMsg() const
Definition Remarks.cpp:98
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition CallGraph.h:229
AttrTypeReplacer.
OptRemarkBase< RemarkKind::RemarkMissed, DiagnosticSeverity::Remark > OptRemarkMissed
Definition Remarks.h:376
llvm::unique_function< void(const Remark &)> ReportFn
Definition Remarks.h:465
OptRemarkBase< RemarkKind::RemarkPassed, DiagnosticSeverity::Remark > OptRemarkPass
Definition Remarks.h:373
OptRemarkBase< RemarkKind::RemarkFailure, DiagnosticSeverity::Remark > OptRemarkFailure
Definition Remarks.h:379
OptRemarkBase< RemarkKind::RemarkAnalysis, DiagnosticSeverity::Remark > OptRemarkAnalysis
Definition Remarks.h:370
InFlightRemark withEngine(Fn fn, Location loc, Args &&...args)
Definition Remarks.h:616
Remark & operator<<(Remark &r, StringRef s)
Definition Remarks.h:346
detail::LazyTextBuild suggest(const char *fmt, Ts &&...ts)
Create a Suggestion with llvm::formatv formatting.
Definition Remarks.h:682
detail::InFlightRemark failed(Location loc, RemarkOpts opts)
Report an optimization remark that failed.
Definition Remarks.h:717
detail::InFlightRemark missed(Location loc, RemarkOpts opts)
Report an optimization remark that was missed.
Definition Remarks.h:711
detail::InFlightRemark analysis(Location loc, RemarkOpts opts)
Report an optimization analysis remark.
Definition Remarks.h:723
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:706
llvm::raw_ostream & operator<<(llvm::raw_ostream &os, RemarkId id)
Definition Remarks.h:57
detail::LazyTextBuild metric(StringRef key, V &&v)
Definition Remarks.h:693
detail::LazyTextBuild reason(const char *fmt, Ts &&...ts)
Create a Reason with llvm::formatv formatting.
Definition Remarks.h:676
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.
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
Definition Diagnostics.h:41
static mlir::remark::detail::Remark getEmptyKey()
Create an empty remark.
Definition Remarks.h:762
static bool isEqual(const mlir::remark::detail::Remark &lhs, const mlir::remark::detail::Remark &rhs)
Definition Remarks.h:786
static mlir::MLIRContext * getStaticDummyContext()
Helper to provide a static dummy context for sentinel keys.
Definition Remarks.h:756
static unsigned getHashValue(const mlir::remark::detail::Remark &remark)
Compute the hash value of the remark.
Definition Remarks.h:778
static mlir::remark::detail::Remark getTombstoneKey()
Create a dead remark.
Definition Remarks.h:770
Define an the set of categories to accept.
Definition Remarks.h:64
std::optional< std::string > missed
Definition Remarks.h:65
std::optional< std::string > all
Definition Remarks.h:65
std::optional< std::string > passed
Definition Remarks.h:65
std::optional< std::string > analysis
Definition Remarks.h:65
std::optional< std::string > failed
Definition Remarks.h:65
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
StringRef subCategoryName
Definition Remarks.h:98
RemarkOpts subCategory(StringRef v) const
Return a copy with the subcategory set.
Definition Remarks.h:118
RemarkOpts relatedTo(RemarkId id) const
Link this remark to a previously emitted remark by explicit ID.
Definition Remarks.h:131
RemarkOpts category(StringRef v) const
Return a copy with the category set.
Definition Remarks.h:112
RemarkId relatedId
Link to a related remark by explicit ID.
Definition Remarks.h:102
static RemarkOpts name(StringRef n)
Definition Remarks.h:105
Lazy text building for zero cost string formatting.
Definition Remarks.h:389
std::function< std::string()> thunk
Definition Remarks.h:391
Arg(llvm::StringRef k, T v)
Definition Remarks.h:194
Arg(llvm::StringRef k, llvm::StringRef v)
Definition Remarks.h:177
Arg(llvm::StringRef k, std::string v)
Definition Remarks.h:178
Arg(llvm::StringRef k, const char *v)
Definition Remarks.h:179
Attribute getAttribute() const
Get the attribute if present.
Definition Remarks.h:189
bool hasAttribute() const
Check if this arg has an associated attribute.
Definition Remarks.h:186
Arg(llvm::StringRef k, bool b)
Definition Remarks.h:183
std::optional< Attribute > attr
Optional attribute storage for Attribute-based args.
Definition Remarks.h:174