[Mlir-commits] [mlir] [MLIR] Introduce RemarkEngine + pluggable remark streaming (YAML/Bitstream) (PR #152474)
Razvan Lupusoru
llvmlistbot at llvm.org
Fri Aug 15 14:09:05 PDT 2025
================
@@ -0,0 +1,467 @@
+//===- Remarks.h - MLIR Optimization Remark ----------------------*- C++-*-===//
+//
+// Part of the LLVM 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines utilities for emitting optimization remarks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_IR_REMARKS_H
+#define MLIR_IR_REMARKS_H
+
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/Remarks/Remark.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/Regex.h"
+#include <optional>
+
+#include "mlir/IR/Diagnostics.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/Value.h"
+
+namespace mlir::remark {
+/// Define an the set of categories to accept. By default none are, the provided
+/// regex matches against the category names for each kind of remark.
+struct RemarkCategories {
+ std::optional<std::string> passed, missed, analysis, failed;
+};
+
+/// Categories describe the outcome of an optimization, not the mechanics of
+/// emitting/serializing remarks.
+enum class RemarkKind {
+ OptimizationRemarkUnknown = 0,
+
+ /// An optimization was applied.
+ OptimizationRemarkPassed,
+
+ /// A profitable optimization opportunity was found but not applied.
+ OptimizationRemarkMissed,
+
+ /// The compiler attempted the optimization but failed (e.g., legality
+ /// checks, or better opportunites).
+ OptimizationRemarkFailure,
+
+ /// Informational context (e.g., analysis numbers) without a pass/fail
+ /// outcome.
+ OptimizationRemarkAnalysis,
+};
+} // namespace mlir::remark
+
+namespace mlir::remark::detail {
+//===----------------------------------------------------------------------===//
+// Remark Base Class
+//===----------------------------------------------------------------------===//
+class Remark {
+
+public:
+ Remark(RemarkKind remarkKind, DiagnosticSeverity severity, StringRef passName,
+ StringRef remarkName, Location loc,
+ std::optional<StringRef> functionName = std::nullopt)
+ : remarkKind(remarkKind), functionName(functionName), loc(loc),
+ passName(passName), remarkName(remarkName) {}
+
+ // Remark argument that is a key-value pair that can be printed as machine
+ // parsable args.
+ struct Arg {
+ std::string key;
+ std::string val;
+ Arg(llvm::StringRef m) : key("Remark"), val(m) {}
+ Arg(llvm::StringRef k, llvm::StringRef v) : key(k), val(v) {}
+ Arg(llvm::StringRef k, std::string v) : key(k), val(std::move(v)) {}
+ Arg(llvm::StringRef k, const char *v) : Arg(k, llvm::StringRef(v)) {}
+ Arg(llvm::StringRef k, Value v);
+ Arg(llvm::StringRef k, Type t);
+ Arg(llvm::StringRef k, bool b) : key(k), val(b ? "true" : "false") {}
+
+ // One constructor for all arithmetic types except bool.
+ template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T> &&
+ !std::is_same_v<T, bool>>>
+ Arg(llvm::StringRef k, T v) : key(k) {
+ if constexpr (std::is_floating_point_v<T>) {
+ llvm::raw_string_ostream os(val);
+ os << v;
+ } else if constexpr (std::is_signed_v<T>) {
+ val = llvm::itostr(static_cast<long long>(v));
+ } else {
+ val = llvm::utostr(static_cast<unsigned long long>(v));
+ }
+ }
+ };
+
+ void insert(llvm::StringRef s);
+ void insert(Arg a);
+
+ void print(llvm::raw_ostream &os, bool printLocation = false) const;
+
+ Location getLocation() const { return loc; }
+ /// Diagnostic -> Remark
+ llvm::remarks::Remark generateRemark() const;
+
+ StringRef getFunction() const {
+ if (functionName)
+ return *functionName;
+ return "<unknown function>";
+ }
+ StringRef getPassName() const { return passName; }
+ StringRef getRemarkName() const { return remarkName; }
+ std::string getMsg() const;
+
+ ArrayRef<Arg> getArgs() const { return args; }
+
+ llvm::remarks::Type getRemarkType() const;
+
+ std::string getRemarkTypeString() const;
+
+protected:
+ /// Keeps the MLIR diagnostic kind, which is used to determine the
+ /// diagnostic kind in the LLVM remark streamer.
+ RemarkKind remarkKind;
+ /// Name of the convering function like interface
+ std::optional<std::string> functionName;
+
+ Location loc;
+ /// Sub category passname e.g., "Unroll" or "UnrollAndJ"
+ StringRef passName;
+
+ /// Remark name, e.g., "LoopOptimizer"
+ StringRef remarkName;
----------------
razvanlupusoru wrote:
how about remarkCategoryName? This makes it clearer and helps explain the "sub category" noted above.
https://github.com/llvm/llvm-project/pull/152474
More information about the Mlir-commits
mailing list