MLIR  22.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 #include <optional>
22 
23 #include "mlir/IR/Diagnostics.h"
24 #include "mlir/IR/MLIRContext.h"
25 #include "mlir/IR/Value.h"
26 
27 namespace mlir::remark {
28 
29 /// Define an the set of categories to accept. By default none are, the provided
30 /// regex matches against the category names for each kind of remark.
32  std::optional<std::string> passed, missed, analysis, failed;
33 };
34 
35 /// Categories describe the outcome of an transformation, not the mechanics of
36 /// emitting/serializing remarks.
37 enum class RemarkKind {
38  RemarkUnknown = 0,
39 
40  /// An optimization was applied.
42 
43  /// A profitable optimization opportunity was found but not applied.
45 
46  /// The compiler attempted the optimization but failed (e.g., legality
47  /// checks, or better opportunites).
49 
50  /// Informational context (e.g., analysis numbers) without a pass/fail
51  /// outcome.
53 };
54 
55 using namespace llvm;
56 
57 /// Options to create a Remark
58 struct RemarkOpts {
59  StringRef remarkName; // Identifiable name
60  StringRef categoryName; // Category name (subject to regex filtering)
61  StringRef subCategoryName; // Subcategory name
62  StringRef functionName; // Function name if available
63 
64  // Construct RemarkOpts from a remark name.
65  static constexpr RemarkOpts name(StringRef n) {
66  return RemarkOpts{n, {}, {}, {}};
67  }
68  /// Return a copy with the category set.
69  constexpr RemarkOpts category(StringRef v) const {
70  return {remarkName, v, subCategoryName, functionName};
71  }
72  /// Return a copy with the subcategory set.
73  constexpr RemarkOpts subCategory(StringRef v) const {
74  return {remarkName, categoryName, v, functionName};
75  }
76  /// Return a copy with the function name set.
77  constexpr RemarkOpts function(StringRef v) const {
78  return {remarkName, categoryName, subCategoryName, v};
79  }
80 };
81 
82 } // namespace mlir::remark
83 
84 namespace mlir::remark::detail {
85 //===----------------------------------------------------------------------===//
86 // Remark Base Class
87 //===----------------------------------------------------------------------===//
88 class Remark {
89 
90 public:
92  RemarkOpts opts)
95  remarkName(opts.remarkName) {
96  if (!categoryName.empty() && !subCategoryName.empty()) {
97  (llvm::Twine(categoryName) + ":" + subCategoryName)
98  .toStringRef(fullCategoryName);
99  }
100  }
101 
102  // Remark argument that is a key-value pair that can be printed as machine
103  // parsable args.
104  struct Arg {
105  std::string key;
106  std::string val;
107  Arg(llvm::StringRef m) : key("Remark"), val(m) {}
108  Arg(llvm::StringRef k, llvm::StringRef v) : key(k), val(v) {}
109  Arg(llvm::StringRef k, std::string v) : key(k), val(std::move(v)) {}
110  Arg(llvm::StringRef k, const char *v) : Arg(k, llvm::StringRef(v)) {}
111  Arg(llvm::StringRef k, Value v);
112  Arg(llvm::StringRef k, Type t);
113  Arg(llvm::StringRef k, bool b) : key(k), val(b ? "true" : "false") {}
114 
115  // One constructor for all arithmetic types except bool.
116  template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T> &&
117  !std::is_same_v<T, bool>>>
118  Arg(llvm::StringRef k, T v) : key(k) {
119  if constexpr (std::is_floating_point_v<T>) {
120  llvm::raw_string_ostream os(val);
121  os << v;
122  } else if constexpr (std::is_signed_v<T>) {
123  val = llvm::itostr(static_cast<long long>(v));
124  } else {
125  val = llvm::utostr(static_cast<unsigned long long>(v));
126  }
127  }
128  };
129 
130  void insert(llvm::StringRef s);
131  void insert(Arg a);
132 
133  void print(llvm::raw_ostream &os, bool printLocation = false) const;
134 
135  Location getLocation() const { return loc; }
136  /// Diagnostic -> Remark
137  llvm::remarks::Remark generateRemark() const;
138 
139  StringRef getFunction() const {
140  if (!functionName.empty())
141  return functionName;
142  return "<unknown function>";
143  }
144 
145  llvm::StringRef getCategoryName() const { return categoryName; }
146 
147  llvm::StringRef getFullCategoryName() const {
148  if (categoryName.empty() && subCategoryName.empty())
149  return {};
150  if (subCategoryName.empty())
151  return categoryName;
152  if (categoryName.empty())
153  return subCategoryName;
154  return fullCategoryName;
155  }
156 
157  StringRef getRemarkName() const {
158  if (remarkName.empty())
159  return "<unknown remark name>";
160  return remarkName;
161  }
162 
163  std::string getMsg() const;
164 
165  ArrayRef<Arg> getArgs() const { return args; }
166 
167  llvm::remarks::Type getRemarkType() const;
168 
169  StringRef getRemarkTypeString() const;
170 
171 protected:
172  /// Keeps the MLIR diagnostic kind, which is used to determine the
173  /// diagnostic kind in the LLVM remark streamer.
175  /// Name of the convering function like interface
176  StringRef functionName;
177 
179  /// Sub category passname e.g., "Unroll" or "UnrollAndJam"
180  StringRef categoryName;
181 
182  /// Sub category name "Loop Optimizer"
183  StringRef subCategoryName;
184 
185  /// Combined name for category and sub-category
187 
188  /// Remark identifier
189  StringRef remarkName;
190 
191  /// Args collected via the streaming interface.
193 
194 private:
195  /// Convert the MLIR diagnostic severity to LLVM diagnostic severity.
197  makeLLVMSeverity(DiagnosticSeverity severity) {
198  switch (severity) {
200  return llvm::DiagnosticSeverity::DS_Note;
202  return llvm::DiagnosticSeverity::DS_Warning;
204  return llvm::DiagnosticSeverity::DS_Error;
206  return llvm::DiagnosticSeverity::DS_Remark;
207  }
208  llvm_unreachable("Unknown diagnostic severity");
209  }
210  /// Convert the MLIR remark kind to LLVM diagnostic kind.
211  static llvm::DiagnosticKind makeLLVMKind(RemarkKind remarkKind) {
212  switch (remarkKind) {
214  return llvm::DiagnosticKind::DK_Generic;
216  return llvm::DiagnosticKind::DK_OptimizationRemark;
218  return llvm::DiagnosticKind::DK_OptimizationRemarkMissed;
220  return llvm::DiagnosticKind::DK_OptimizationFailure;
222  return llvm::DiagnosticKind::DK_OptimizationRemarkAnalysis;
223  }
224  llvm_unreachable("Unknown diagnostic kind");
225  }
226 };
227 
228 inline Remark &operator<<(Remark &r, StringRef s) {
229  r.insert(s);
230  return r;
231 }
232 inline Remark &&operator<<(Remark &&r, StringRef s) {
233  r.insert(s);
234  return std::move(r);
235 }
236 inline Remark &operator<<(Remark &r, const Remark::Arg &kv) {
237  r.insert(kv);
238  return r;
239 }
240 
241 //===----------------------------------------------------------------------===//
242 // Shorthand aliases for different kinds of remarks.
243 //===----------------------------------------------------------------------===//
244 
245 template <RemarkKind K, DiagnosticSeverity S>
246 class OptRemarkBase final : public Remark {
247 public:
249  : Remark(K, S, loc, opts) {}
250 };
251 
254 
257 
260 
263 
264 class RemarkEngine;
265 
266 //===----------------------------------------------------------------------===//
267 // InFlightRemark
268 //===----------------------------------------------------------------------===//
269 
270 /// Lazy text building for zero cost string formatting.
272  llvm::StringRef key;
273  std::function<std::string()> thunk;
274 };
275 
276 /// InFlightRemark is a RAII class that holds a reference to a Remark
277 /// instance and allows to build the remark using the << operator. The remark
278 /// is emitted when the InFlightRemark instance is destroyed, which happens
279 /// when the scope ends or when the InFlightRemark instance is moved.
280 /// Similar to InFlightDiagnostic, but for remarks.
282 public:
283  explicit InFlightRemark(std::unique_ptr<Remark> diag)
284  : remark(std::move(diag)) {}
285 
286  InFlightRemark(RemarkEngine &eng, std::unique_ptr<Remark> diag)
287  : owner(&eng), remark(std::move(diag)) {}
288 
289  InFlightRemark() = default; // empty ctor
290 
292  if (remark)
293  *remark << Remark::Arg(l.key, l.thunk());
294  return *this;
295  }
296 
297  // Generic path, but *not* for Lazy
298  template <typename T, typename = std::enable_if_t<
299  !std::is_same_v<std::decay_t<T>, LazyTextBuild>>>
301  if (remark)
302  *remark << std::forward<T>(arg);
303  return *this;
304  }
305 
306  explicit operator bool() const { return remark != nullptr; }
307 
308  ~InFlightRemark();
309 
310  InFlightRemark(const InFlightRemark &) = delete;
314 
315 private:
316  RemarkEngine *owner{nullptr};
317  std::unique_ptr<Remark> remark;
318 };
319 
320 //===----------------------------------------------------------------------===//
321 // MLIR Remark Streamer
322 //===----------------------------------------------------------------------===//
323 
324 /// Base class for MLIR remark streamers that is used to stream
325 /// optimization remarks to the underlying remark streamer. The derived classes
326 /// should implement the `streamOptimizationRemark` method to provide the
327 /// actual streaming implementation.
329 public:
330  virtual ~MLIRRemarkStreamerBase() = default;
331  /// Stream an optimization remark to the underlying remark streamer. It is
332  /// called by the RemarkEngine to stream the optimization remarks.
333  ///
334  /// It must be overridden by the derived classes to provide
335  /// the actual streaming implementation.
336  virtual void streamOptimizationRemark(const Remark &remark) = 0;
337 
338  virtual void finalize() {} // optional
339 };
340 
341 //===----------------------------------------------------------------------===//
342 // Remark Engine (MLIR Context will own this class)
343 //===----------------------------------------------------------------------===//
344 
346 private:
347  /// Regex that filters missed optimization remarks: only matching one are
348  /// reported.
349  std::optional<llvm::Regex> missFilter;
350  /// The category for passed optimization remarks.
351  std::optional<llvm::Regex> passedFilter;
352  /// The category for analysis remarks.
353  std::optional<llvm::Regex> analysisFilter;
354  /// The category for failed optimization remarks.
355  std::optional<llvm::Regex> failedFilter;
356  /// The MLIR remark streamer that will be used to emit the remarks.
357  std::unique_ptr<MLIRRemarkStreamerBase> remarkStreamer;
358  /// When is enabled, engine also prints remarks as mlir::emitRemarks.
359  bool printAsEmitRemarks = false;
360 
361  /// Return true if missed optimization remarks are enabled, override
362  /// to provide different implementation.
363  bool isMissedOptRemarkEnabled(StringRef categoryName) const;
364 
365  /// Return true if passed optimization remarks are enabled, override
366  /// to provide different implementation.
367  bool isPassedOptRemarkEnabled(StringRef categoryName) const;
368 
369  /// Return true if analysis optimization remarks are enabled, override
370  /// to provide different implementation.
371  bool isAnalysisOptRemarkEnabled(StringRef categoryName) const;
372 
373  /// Return true if analysis optimization remarks are enabled, override
374  /// to provide different implementation.
375  bool isFailedOptRemarkEnabled(StringRef categoryName) const;
376 
377  /// Return true if any type of remarks are enabled for this pass.
378  bool isAnyRemarkEnabled(StringRef categoryName) const {
379  return isMissedOptRemarkEnabled(categoryName) ||
380  isPassedOptRemarkEnabled(categoryName) ||
381  isFailedOptRemarkEnabled(categoryName) ||
382  isAnalysisOptRemarkEnabled(categoryName);
383  }
384 
385  /// Emit a remark using the given maker function, which should return
386  /// a Remark instance. The remark will be emitted using the main
387  /// remark streamer.
388  template <typename RemarkT, typename... Args>
389  InFlightRemark makeRemark(Args &&...args);
390 
391  template <typename RemarkT>
392  InFlightRemark emitIfEnabled(Location loc, RemarkOpts opts,
393  bool (RemarkEngine::*isEnabled)(StringRef)
394  const);
395 
396 public:
397  /// Default constructor is deleted, use the other constructor.
398  RemarkEngine() = delete;
399 
400  /// Constructs Remark engine with optional category names. If a category
401  /// name is not provided, it is not enabled. The category names are used to
402  /// filter the remarks that are emitted.
403  RemarkEngine(bool printAsEmitRemarks, const RemarkCategories &cats);
404 
405  /// Destructor that will close the output file and reset the
406  /// main remark streamer.
407  ~RemarkEngine();
408 
409  /// Setup the remark engine with the given output path and format.
410  LogicalResult initialize(std::unique_ptr<MLIRRemarkStreamerBase> streamer,
411  std::string *errMsg);
412 
413  /// Report a remark.
414  void report(const Remark &&remark);
415 
416  /// Report a successful remark, this will create an InFlightRemark
417  /// that can be used to build the remark using the << operator.
419 
420  /// Report a missed optimization remark
421  /// that can be used to build the remark using the << operator.
423 
424  /// Report a failed optimization remark, this will create an InFlightRemark
425  /// that can be used to build the remark using the << operator.
427 
428  /// Report an analysis remark, this will create an InFlightRemark
429  /// that can be used to build the remark using the << operator.
431 };
432 
433 template <typename Fn, typename... Args>
434 inline InFlightRemark withEngine(Fn fn, Location loc, Args &&...args) {
435  MLIRContext *ctx = loc->getContext();
436 
437  RemarkEngine *enginePtr = ctx->getRemarkEngine();
438 
439  if (LLVM_UNLIKELY(enginePtr))
440  return (enginePtr->*fn)(loc, std::forward<Args>(args)...);
441 
442  return {};
443 }
444 
445 } // namespace mlir::remark::detail
446 
447 namespace mlir::remark {
448 
449 /// Create a Reason with llvm::formatv formatting.
450 template <class... Ts>
451 inline detail::LazyTextBuild reason(const char *fmt, Ts &&...ts) {
452  return {"Reason", [=] { return llvm::formatv(fmt, ts...).str(); }};
453 }
454 
455 /// Create a Suggestion with llvm::formatv formatting.
456 template <class... Ts>
457 inline detail::LazyTextBuild suggest(const char *fmt, Ts &&...ts) {
458  return {"Suggestion", [=] { return llvm::formatv(fmt, ts...).str(); }};
459 }
460 
461 /// Create a Remark with llvm::formatv formatting.
462 template <class... Ts>
463 inline detail::LazyTextBuild add(const char *fmt, Ts &&...ts) {
464  return {"Remark", [=] { return llvm::formatv(fmt, ts...).str(); }};
465 }
466 
467 template <class V>
468 inline detail::LazyTextBuild metric(StringRef key, V &&v) {
469  using DV = std::decay_t<V>;
470  return {key, [key, vv = DV(std::forward<V>(v))]() mutable {
471  // Reuse Arg's formatting logic and return just the value string.
472  return detail::Remark::Arg(key, std::move(vv)).val;
473  }};
474 }
475 //===----------------------------------------------------------------------===//
476 // Emitters
477 //===----------------------------------------------------------------------===//
478 
479 /// Report an optimization remark that was passed.
482 }
483 
484 /// Report an optimization remark that was missed.
487  opts);
488 }
489 
490 /// Report an optimization remark that failed.
493  opts);
494 }
495 
496 /// Report an optimization analysis remark.
499  opts);
500 }
501 
502 //===----------------------------------------------------------------------===//
503 // Setup
504 //===----------------------------------------------------------------------===//
505 
506 /// Setup remarks for the context. This function will enable the remark engine
507 /// and set the streamer to be used for optimization remarks. The remark
508 /// categories are used to filter the remarks that will be emitted by the remark
509 /// engine. If a category is not specified, it will not be emitted. If
510 /// `printAsEmitRemarks` is true, the remarks will be printed as
511 /// mlir::emitRemarks. 'streamer' must inherit from MLIRRemarkStreamerBase and
512 /// will be used to stream the remarks.
514  MLIRContext &ctx,
515  std::unique_ptr<remark::detail::MLIRRemarkStreamerBase> streamer,
516  const remark::RemarkCategories &cats, bool printAsEmitRemarks = false);
517 
518 } // namespace mlir::remark
519 
520 #endif // MLIR_IR_REMARKS_H
static std::string diag(const llvm::Value &value)
MLIRContext * getContext() const
Return the context this attribute belongs to.
Definition: Attributes.cpp:37
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: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
InFlightRemark is a RAII class that holds a reference to a Remark instance and allows to build the re...
Definition: Remarks.h:281
InFlightRemark & operator<<(const LazyTextBuild &l)
Definition: Remarks.h:291
InFlightRemark(RemarkEngine &eng, std::unique_ptr< Remark > diag)
Definition: Remarks.h:286
InFlightRemark(std::unique_ptr< Remark > diag)
Definition: Remarks.h:283
InFlightRemark(const InFlightRemark &)=delete
InFlightRemark & operator=(const InFlightRemark &)=delete
InFlightRemark(InFlightRemark &&)=default
InFlightRemark & operator=(InFlightRemark &&)=default
InFlightRemark & operator<<(T &&arg)
Definition: Remarks.h:300
Base class for MLIR remark streamers that is used to stream optimization remarks to the underlying re...
Definition: Remarks.h:328
virtual void streamOptimizationRemark(const Remark &remark)=0
Stream an optimization remark to the underlying remark streamer.
OptRemarkBase(Location loc, RemarkOpts opts)
Definition: Remarks.h:248
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:212
LogicalResult initialize(std::unique_ptr< MLIRRemarkStreamerBase > streamer, std::string *errMsg)
Setup the remark engine with the given output path and format.
Definition: Remarks.cpp:244
void report(const Remark &&remark)
Report a remark.
Definition: Remarks.cpp:228
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:200
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:206
~RemarkEngine()
Destructor that will close the output file and reset the main remark streamer.
Definition: Remarks.cpp:238
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:218
llvm::StringRef getFullCategoryName() const
Definition: Remarks.h:147
void print(llvm::raw_ostream &os, bool printLocation=false) const
Print the remark to the given output stream.
Definition: Remarks.cpp:70
StringRef categoryName
Sub category passname e.g., "Unroll" or "UnrollAndJam".
Definition: Remarks.h:180
SmallVector< Arg, 4 > args
Args collected via the streaming interface.
Definition: Remarks.h:192
llvm::StringRef getCategoryName() const
Definition: Remarks.h:145
StringRef getFunction() const
Definition: Remarks.h:139
Remark(RemarkKind remarkKind, DiagnosticSeverity severity, Location loc, RemarkOpts opts)
Definition: Remarks.h:91
llvm::remarks::Type getRemarkType() const
Definition: Remarks.cpp:116
StringRef getRemarkTypeString() const
Definition: Remarks.cpp:100
StringRef subCategoryName
Sub category name "Loop Optimizer".
Definition: Remarks.h:183
Location getLocation() const
Definition: Remarks.h:135
StringRef remarkName
Remark identifier.
Definition: Remarks.h:189
ArrayRef< Arg > getArgs() const
Definition: Remarks.h:165
RemarkKind remarkKind
Keeps the MLIR diagnostic kind, which is used to determine the diagnostic kind in the LLVM remark str...
Definition: Remarks.h:174
StringRef getRemarkName() const
Definition: Remarks.h:157
SmallString< 64 > fullCategoryName
Combined name for category and sub-category.
Definition: Remarks.h:186
void insert(llvm::StringRef s)
Definition: Remarks.cpp:34
StringRef functionName
Name of the convering function like interface.
Definition: Remarks.h:176
llvm::remarks::Remark generateRemark() const
Diagnostic -> Remark.
Definition: Remarks.cpp:132
std::string getMsg() const
Definition: Remarks.cpp:92
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
InFlightRemark withEngine(Fn fn, Location loc, Args &&...args)
Definition: Remarks.h:434
Remark & operator<<(Remark &r, StringRef s)
Definition: Remarks.h:228
detail::LazyTextBuild suggest(const char *fmt, Ts &&...ts)
Create a Suggestion with llvm::formatv formatting.
Definition: Remarks.h:457
detail::InFlightRemark failed(Location loc, RemarkOpts opts)
Report an optimization remark that failed.
Definition: Remarks.h:491
detail::InFlightRemark missed(Location loc, RemarkOpts opts)
Report an optimization remark that was missed.
Definition: Remarks.h:485
LogicalResult enableOptimizationRemarks(MLIRContext &ctx, std::unique_ptr< remark::detail::MLIRRemarkStreamerBase > streamer, const remark::RemarkCategories &cats, bool printAsEmitRemarks=false)
Setup remarks for the context.
detail::InFlightRemark analysis(Location loc, RemarkOpts opts)
Report an optimization analysis remark.
Definition: Remarks.h:497
detail::LazyTextBuild add(const char *fmt, Ts &&...ts)
Create a Remark with llvm::formatv formatting.
Definition: Remarks.h:463
detail::InFlightRemark passed(Location loc, RemarkOpts opts)
Report an optimization remark that was passed.
Definition: Remarks.h:480
detail::LazyTextBuild metric(StringRef key, V &&v)
Definition: Remarks.h:468
detail::LazyTextBuild reason(const char *fmt, Ts &&...ts)
Create a Reason with llvm::formatv formatting.
Definition: Remarks.h:451
RemarkKind
Categories describe the outcome of an transformation, not the mechanics of emitting/serializing remar...
Definition: Remarks.h:37
@ RemarkPassed
An optimization was applied.
@ RemarkAnalysis
Informational context (e.g., analysis numbers) without a pass/fail outcome.
@ RemarkMissed
A profitable optimization opportunity was found but not applied.
@ RemarkFailure
The compiler attempted the optimization but failed (e.g., legality checks, or better opportunites).
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
Definition: Diagnostics.h:40
Define an the set of categories to accept.
Definition: Remarks.h:31
std::optional< std::string > missed
Definition: Remarks.h:32
std::optional< std::string > passed
Definition: Remarks.h:32
std::optional< std::string > analysis
Definition: Remarks.h:32
std::optional< std::string > failed
Definition: Remarks.h:32
Options to create a Remark.
Definition: Remarks.h:58
StringRef subCategoryName
Definition: Remarks.h:61
StringRef categoryName
Definition: Remarks.h:60
static constexpr RemarkOpts name(StringRef n)
Definition: Remarks.h:65
constexpr RemarkOpts category(StringRef v) const
Return a copy with the category set.
Definition: Remarks.h:69
constexpr RemarkOpts subCategory(StringRef v) const
Return a copy with the subcategory set.
Definition: Remarks.h:73
StringRef remarkName
Definition: Remarks.h:59
StringRef functionName
Definition: Remarks.h:62
Lazy text building for zero cost string formatting.
Definition: Remarks.h:271
std::function< std::string()> thunk
Definition: Remarks.h:273
Arg(llvm::StringRef k, T v)
Definition: Remarks.h:118
Arg(llvm::StringRef k, llvm::StringRef v)
Definition: Remarks.h:108
Arg(llvm::StringRef k, std::string v)
Definition: Remarks.h:109
Arg(llvm::StringRef k, const char *v)
Definition: Remarks.h:110
Arg(llvm::StringRef m)
Definition: Remarks.h:107
Arg(llvm::StringRef k, bool b)
Definition: Remarks.h:113