[Mlir-commits] [mlir] [MLIR][Remark] Import LLVM optimization remarks into the remark engine (PR #222300)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Sep 9 04:17:20 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-nvptx

@llvm/pr-subscribers-mlir-bufferization

Author: Guray Ozen (grypp)

<details>
<summary>Changes</summary>

Collect LLVM side of remarks with MLIR's remark infra.

LLVM passes emit their own [optimization remarks](https://llvm.org/docs/Remarks.html) and MLIR has own. This PR bridges MLIR and LLVM remarks.  

`ModuleToObject` installs a `remark::LLVMToMLIRDiagnosticHandler` on the `llvm::LLVMContext` it compiles with, which imports these remarks into the remark engine: the category is the LLVM pass name prefixed with `llvm-`, the LLVM remark name becomes the name, the message is stored under the `Remark` argument and the structured LLVM arguments are copied as metrics. The remark filters therefore select LLVM remarks by pass name, and `llvm-.*` selects all of them.

---

Patch is 43.62 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/222300.diff


14 Files Affected:

- (modified) mlir/docs/Remarks.md (+35) 
- (added) mlir/include/mlir/Remark/LLVMRemarkImport.h (+70) 
- (modified) mlir/include/mlir/Target/LLVM/ModuleToObject.h (+6) 
- (modified) mlir/lib/Remark/CMakeLists.txt (+1) 
- (added) mlir/lib/Remark/LLVMRemarkImport.cpp (+315) 
- (modified) mlir/lib/Target/LLVM/CMakeLists.txt (+1) 
- (modified) mlir/lib/Target/LLVM/ModuleToObject.cpp (+8) 
- (added) mlir/test/Dialect/GPU/module-to-binary-nvvm-remarks.mlir (+30) 
- (modified) mlir/test/lib/Dialect/Bufferization/TestOneShotModuleBufferize.cpp (+1) 
- (modified) mlir/test/lib/Dialect/Test/TestOpDefs.cpp (+1) 
- (modified) mlir/unittests/CMakeLists.txt (+1) 
- (added) mlir/unittests/Remark/CMakeLists.txt (+9) 
- (added) mlir/unittests/Remark/LLVMRemarkImportTest.cpp (+395) 
- (modified) mlir/unittests/Target/LLVM/SerializeNVVMTarget.cpp (+81) 


``````````diff
diff --git a/mlir/docs/Remarks.md b/mlir/docs/Remarks.md
index 43f5d4da12247..c70e20cd44ec4 100644
--- a/mlir/docs/Remarks.md
+++ b/mlir/docs/Remarks.md
@@ -326,3 +326,38 @@ public:
 auto streamer = std::make_unique<MyStreamer>();
 remark::enableOptimizationRemarks(context, std::move(streamer), cats);
 ```
+
+***
+
+## Importing LLVM Remarks
+
+LLVM passes emit their own
+[optimization remarks](https://llvm.org/docs/Remarks.html) while MLIR compiles
+a module with LLVM, for example in `gpu-module-to-binary`. `ModuleToObject`
+installs a `remark::LLVMToMLIRDiagnosticHandler` on the `llvm::LLVMContext` it
+compiles with, which imports these remarks into the remark engine: the category
+is the LLVM pass name prefixed with `llvm-`, the LLVM remark name becomes the
+name, the message is stored under the `Remark` argument and the structured LLVM
+arguments are copied as metrics. The remark filters therefore select LLVM
+remarks by pass name, and `llvm-.*` selects all of them:
+
+```
+mlir-opt kernel.mlir --gpu-module-to-binary="format=isa" --remarks-filter-passed=llvm-inline
+```
+
+```
+[Passed] Inlined | Category:llvm-inline | Function=kernel | Callee=helper, Caller=kernel, Cost=-30, Remark="'helper' inlined into 'kernel' with (cost=-30, threshold=337)", Threshold=337
+```
+
+Remarks that are not enabled in the engine are left to LLVM, so LLVM's
+`-pass-remarks` flags keep working. Other LLVM diagnostics, such as errors
+reported by a backend, become MLIR diagnostics.
+
+LLVM remarks carry a source location only when the LLVM IR has debug
+information; run `ensure-debug-info-scope-on-llvm-func` before serializing to
+get `file:line:column` locations. Otherwise a remark is attached to the MLIR
+symbol named after its LLVM function, or to the serialized operation.
+
+Remarks saved by an LLVM-based compiler to a YAML or bitstream file can be
+replayed into the engine with `remark::importLLVMRemarks`, which applies the
+same conversion.
diff --git a/mlir/include/mlir/Remark/LLVMRemarkImport.h b/mlir/include/mlir/Remark/LLVMRemarkImport.h
new file mode 100644
index 0000000000000..ccacb70e4c1b0
--- /dev/null
+++ b/mlir/include/mlir/Remark/LLVMRemarkImport.h
@@ -0,0 +1,70 @@
+//===- LLVMRemarkImport.h - Import LLVM remarks into MLIR -------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities to import LLVM optimization remarks into the MLIR remark engine,
+// either as they are emitted by LLVM passes or from a serialized remark file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_REMARK_LLVMREMARKIMPORT_H
+#define MLIR_REMARK_LLVMREMARKIMPORT_H
+
+#include "mlir/IR/Location.h"
+#include "mlir/IR/Remarks.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/IR/DiagnosticHandler.h"
+#include "llvm/Remarks/RemarkFormat.h"
+
+namespace mlir {
+class Operation;
+
+namespace remark {
+
+/// Prefix of the category of remarks imported from LLVM. The category is the
+/// prefix followed by the LLVM pass name, e.g. `llvm-inline`, so that remark
+/// filters can select LLVM remarks (`llvm-.*`) or a single LLVM pass.
+constexpr llvm::StringLiteral llvmRemarkCategoryPrefix = "llvm-";
+
+/// Parses `buffer`, a serialized LLVM remark file, and reports its remarks into
+/// the remark engine of the context of `anchor`, the operation the remarks
+/// refer to. The category is the prefixed LLVM pass name, the LLVM remark name
+/// becomes the remark name and the message is stored under the "Remark"
+/// argument. A remark is attached to its debug location if it has one,
+/// otherwise to the symbol named after its LLVM function inside `anchor`,
+/// otherwise to `anchor`. Fails if the buffer cannot be parsed.
+LogicalResult importLLVMRemarks(Operation *anchor, StringRef buffer,
+                                llvm::remarks::Format format);
+
+/// Diagnostic handler forwarding LLVM diagnostics to MLIR. Optimization remarks
+/// enabled in the remark engine of the context of `anchor` are imported as
+/// described for `importLLVMRemarks`, so the remark filters of the engine
+/// select LLVM remarks by their prefixed pass name. Other remarks are left to
+/// LLVM, which prints those enabled with its own `-pass-remarks` flags. All
+/// other diagnostics are reported as MLIR diagnostics. Install the handler with
+/// `RespectFilters` set, so that LLVM only forwards enabled remarks.
+class LLVMToMLIRDiagnosticHandler : public llvm::DiagnosticHandler {
+public:
+  explicit LLVMToMLIRDiagnosticHandler(Operation *anchor);
+
+  bool handleDiagnostics(const llvm::DiagnosticInfo &diag) override;
+  bool isAnalysisRemarkEnabled(StringRef passName) const override;
+  bool isMissedOptRemarkEnabled(StringRef passName) const override;
+  bool isPassedOptRemarkEnabled(StringRef passName) const override;
+  using llvm::DiagnosticHandler::isAnyRemarkEnabled;
+  bool isAnyRemarkEnabled() const override;
+
+private:
+  Operation *anchor;
+  detail::RemarkEngine *engine;
+  llvm::StringMap<Location> functionLocations;
+};
+
+} // namespace remark
+} // namespace mlir
+
+#endif // MLIR_REMARK_LLVMREMARKIMPORT_H
diff --git a/mlir/include/mlir/Target/LLVM/ModuleToObject.h b/mlir/include/mlir/Target/LLVM/ModuleToObject.h
index 7d232dcf9ab90..4ae634a372a8e 100644
--- a/mlir/include/mlir/Target/LLVM/ModuleToObject.h
+++ b/mlir/include/mlir/Target/LLVM/ModuleToObject.h
@@ -53,6 +53,12 @@ class ModuleToObject {
 protected:
   // Hooks to be implemented by derived classes.
 
+  /// Hook for configuring the LLVM context, called by `run` before translating
+  /// the operation. By default it installs a
+  /// `remark::LLVMToMLIRDiagnosticHandler` to report LLVM diagnostics and
+  /// remarks through MLIR.
+  virtual void setupLLVMContext(llvm::LLVMContext &llvmContext);
+
   /// Hook for computing the Datalayout
   virtual void setDataLayoutAndTriple(llvm::Module &module);
 
diff --git a/mlir/lib/Remark/CMakeLists.txt b/mlir/lib/Remark/CMakeLists.txt
index 920a95db4f07b..a75c17288d5b6 100644
--- a/mlir/lib/Remark/CMakeLists.txt
+++ b/mlir/lib/Remark/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_mlir_library(MLIRRemarkStreamer
+  LLVMRemarkImport.cpp
   RemarkStreamer.cpp
 
   ADDITIONAL_HEADER_DIRS
diff --git a/mlir/lib/Remark/LLVMRemarkImport.cpp b/mlir/lib/Remark/LLVMRemarkImport.cpp
new file mode 100644
index 0000000000000..5b89e5fda6aa1
--- /dev/null
+++ b/mlir/lib/Remark/LLVMRemarkImport.cpp
@@ -0,0 +1,315 @@
+//===- LLVMRemarkImport.cpp - Import LLVM remarks into MLIR ---------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Remark/LLVMRemarkImport.h"
+
+#include "mlir/IR/Diagnostics.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/Operation.h"
+#include "mlir/IR/SymbolTable.h"
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/Remarks/Remark.h"
+#include "llvm/Remarks/RemarkParser.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace mlir;
+
+//===----------------------------------------------------------------------===//
+// Locations
+//===----------------------------------------------------------------------===//
+
+/// Returns the location of the symbol `functionName` inside `anchor`, or the
+/// location of `anchor` if there is no such symbol.
+static Location getFunctionLocation(Operation *anchor,
+                                    llvm::StringMap<Location> &cache,
+                                    StringRef functionName) {
+  if (functionName.empty() || !anchor->hasTrait<OpTrait::SymbolTable>())
+    return anchor->getLoc();
+  auto it = cache.find(functionName);
+  if (it != cache.end())
+    return it->second;
+  Location loc = anchor->getLoc();
+  if (Operation *symbol = SymbolTable::lookupSymbolIn(anchor, functionName))
+    loc = symbol->getLoc();
+  cache.try_emplace(functionName, loc);
+  return loc;
+}
+
+static Location resolveLocation(Operation *anchor,
+                                llvm::StringMap<Location> &cache,
+                                StringRef file, unsigned line, unsigned column,
+                                StringRef functionName) {
+  if (!file.empty() && line != 0)
+    return FileLineColLoc::get(anchor->getContext(), file, line, column);
+  return getFunctionLocation(anchor, cache, functionName);
+}
+
+static Location
+resolveLocation(Operation *anchor, llvm::StringMap<Location> &cache,
+                const llvm::DiagnosticInfoWithLocationBase &diag) {
+  StringRef functionName = diag.getFunction().getName();
+  if (!diag.isLocationAvailable())
+    return resolveLocation(anchor, cache, "", 0, 0, functionName);
+  llvm::DiagnosticLocation loc = diag.getLocation();
+  return resolveLocation(anchor, cache, loc.getAbsolutePath(), loc.getLine(),
+                         loc.getColumn(), functionName);
+}
+
+//===----------------------------------------------------------------------===//
+// Remark conversion
+//===----------------------------------------------------------------------===//
+
+namespace {
+/// The fields of an LLVM remark that are imported, shared by the live and the
+/// serialized paths.
+struct ImportedRemark {
+  remark::RemarkKind kind = remark::RemarkKind::RemarkUnknown;
+  StringRef passName;
+  StringRef remarkName;
+  StringRef functionName;
+  std::string message;
+  std::optional<uint64_t> hotness;
+  SmallVector<std::pair<StringRef, StringRef>> args;
+};
+} // namespace
+
+static remark::RemarkKind getRemarkKind(llvm::DiagnosticKind kind) {
+  switch (kind) {
+  case llvm::DK_OptimizationRemark:
+  case llvm::DK_MachineOptimizationRemark:
+    return remark::RemarkKind::RemarkPassed;
+  case llvm::DK_OptimizationRemarkMissed:
+  case llvm::DK_MachineOptimizationRemarkMissed:
+    return remark::RemarkKind::RemarkMissed;
+  case llvm::DK_OptimizationRemarkAnalysis:
+  case llvm::DK_OptimizationRemarkAnalysisFPCommute:
+  case llvm::DK_OptimizationRemarkAnalysisAliasing:
+  case llvm::DK_MachineOptimizationRemarkAnalysis:
+    return remark::RemarkKind::RemarkAnalysis;
+  case llvm::DK_OptimizationFailure:
+    return remark::RemarkKind::RemarkFailure;
+  default:
+    return remark::RemarkKind::RemarkUnknown;
+  }
+}
+
+static remark::RemarkKind getRemarkKind(llvm::remarks::Type type) {
+  switch (type) {
+  case llvm::remarks::Type::Passed:
+    return remark::RemarkKind::RemarkPassed;
+  case llvm::remarks::Type::Missed:
+    return remark::RemarkKind::RemarkMissed;
+  case llvm::remarks::Type::Analysis:
+  case llvm::remarks::Type::AnalysisFPCommute:
+  case llvm::remarks::Type::AnalysisAliasing:
+    return remark::RemarkKind::RemarkAnalysis;
+  case llvm::remarks::Type::Failure:
+    return remark::RemarkKind::RemarkFailure;
+  case llvm::remarks::Type::Unknown:
+    return remark::RemarkKind::RemarkUnknown;
+  }
+  llvm_unreachable("unknown remark type");
+}
+
+/// Returns the MLIR remark category of the LLVM pass `passName`.
+static std::string getCategory(StringRef passName) {
+  return (llvm::Twine(remark::llvmRemarkCategoryPrefix) + passName).str();
+}
+
+/// Renames the argument keys that the remark engine uses itself.
+static std::string getArgKey(StringRef key) {
+  if (key == "Remark" || key == "RemarkId" || key == "RelatedTo")
+    return ("LLVM" + key).str();
+  return key.str();
+}
+
+static void emitImportedRemark(remark::detail::RemarkEngine &engine,
+                               Location loc, const ImportedRemark &imported) {
+  std::string category = getCategory(imported.passName);
+  remark::RemarkOpts opts = remark::RemarkOpts::name(imported.remarkName)
+                                .category(category)
+                                .function(imported.functionName);
+  remark::detail::InFlightRemark inFlight;
+  switch (imported.kind) {
+  case remark::RemarkKind::RemarkPassed:
+    inFlight = engine.emitOptimizationRemark(loc, opts);
+    break;
+  case remark::RemarkKind::RemarkMissed:
+    inFlight = engine.emitOptimizationRemarkMiss(loc, opts);
+    break;
+  case remark::RemarkKind::RemarkFailure:
+    inFlight = engine.emitOptimizationRemarkFailure(loc, opts);
+    break;
+  case remark::RemarkKind::RemarkAnalysis:
+    inFlight = engine.emitOptimizationRemarkAnalysis(loc, opts);
+    break;
+  case remark::RemarkKind::RemarkUnknown:
+    return;
+  }
+  if (!inFlight)
+    return;
+
+  inFlight << StringRef(imported.message);
+  for (const auto &[key, value] : imported.args) {
+    // Plain strings are already part of the message.
+    if (key == "String")
+      continue;
+    inFlight << remark::detail::Remark::Arg(getArgKey(key), value);
+  }
+  if (imported.hotness)
+    inFlight << remark::detail::Remark::Arg("Hotness", *imported.hotness);
+}
+
+static void importLLVMRemark(remark::detail::RemarkEngine &engine, Location loc,
+                             const llvm::DiagnosticInfoOptimizationBase &diag) {
+  ImportedRemark imported;
+  imported.kind =
+      getRemarkKind(static_cast<llvm::DiagnosticKind>(diag.getKind()));
+  imported.passName = diag.getPassName();
+  imported.remarkName = diag.getRemarkName();
+  imported.functionName =
+      llvm::GlobalValue::dropLLVMManglingEscape(diag.getFunction().getName());
+  imported.message = diag.getMsg();
+  imported.hotness = diag.getHotness();
+  for (const llvm::DiagnosticInfoOptimizationBase::Argument &arg :
+       diag.getArgs())
+    imported.args.emplace_back(arg.Key, arg.Val);
+  emitImportedRemark(engine, loc, imported);
+}
+
+static void importLLVMRemark(remark::detail::RemarkEngine &engine, Location loc,
+                             const llvm::remarks::Remark &remark) {
+  ImportedRemark imported;
+  imported.kind = getRemarkKind(remark.RemarkType);
+  imported.passName = remark.PassName;
+  imported.remarkName = remark.RemarkName;
+  imported.functionName = remark.FunctionName;
+  imported.message = remark.getArgsAsMsg();
+  imported.hotness = remark.Hotness;
+  for (const llvm::remarks::Argument &arg : remark.Args)
+    imported.args.emplace_back(arg.Key, arg.Val);
+  emitImportedRemark(engine, loc, imported);
+}
+
+LogicalResult mlir::remark::importLLVMRemarks(Operation *anchor,
+                                              StringRef buffer,
+                                              llvm::remarks::Format format) {
+  remark::detail::RemarkEngine *engine =
+      anchor->getContext()->getRemarkEngine();
+  if (!engine)
+    return success();
+
+  llvm::Expected<std::unique_ptr<llvm::remarks::RemarkParser>> parser =
+      llvm::remarks::createRemarkParser(format, buffer);
+  if (!parser) {
+    llvm::consumeError(parser.takeError());
+    return failure();
+  }
+
+  llvm::StringMap<Location> functionLocations;
+  while (true) {
+    llvm::Expected<std::unique_ptr<llvm::remarks::Remark>> next =
+        (*parser)->next();
+    if (!next) {
+      llvm::Error error = next.takeError();
+      bool endOfFile = error.isA<llvm::remarks::EndOfFileError>();
+      llvm::consumeError(std::move(error));
+      return success(endOfFile);
+    }
+    const llvm::remarks::Remark &remark = **next;
+    Location loc = remark.Loc ? resolveLocation(anchor, functionLocations,
+                                                remark.Loc->SourceFilePath,
+                                                remark.Loc->SourceLine,
+                                                remark.Loc->SourceColumn,
+                                                remark.FunctionName)
+                              : resolveLocation(anchor, functionLocations, "",
+                                                0, 0, remark.FunctionName);
+    importLLVMRemark(*engine, loc, remark);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// LLVMToMLIRDiagnosticHandler
+//===----------------------------------------------------------------------===//
+
+remark::LLVMToMLIRDiagnosticHandler::LLVMToMLIRDiagnosticHandler(
+    Operation *anchor)
+    : anchor(anchor), engine(anchor->getContext()->getRemarkEngine()) {}
+
+bool remark::LLVMToMLIRDiagnosticHandler::isAnalysisRemarkEnabled(
+    StringRef passName) const {
+  return (engine &&
+          engine->isAnalysisOptRemarkEnabled(getCategory(passName))) ||
+         DiagnosticHandler::isAnalysisRemarkEnabled(passName);
+}
+
+bool remark::LLVMToMLIRDiagnosticHandler::isMissedOptRemarkEnabled(
+    StringRef passName) const {
+  return (engine && engine->isMissedOptRemarkEnabled(getCategory(passName))) ||
+         DiagnosticHandler::isMissedOptRemarkEnabled(passName);
+}
+
+bool remark::LLVMToMLIRDiagnosticHandler::isPassedOptRemarkEnabled(
+    StringRef passName) const {
+  return (engine && engine->isPassedOptRemarkEnabled(getCategory(passName))) ||
+         DiagnosticHandler::isPassedOptRemarkEnabled(passName);
+}
+
+bool remark::LLVMToMLIRDiagnosticHandler::isAnyRemarkEnabled() const {
+  return (engine && engine->isAnyRemarkEnabled()) ||
+         DiagnosticHandler::isAnyRemarkEnabled();
+}
+
+bool remark::LLVMToMLIRDiagnosticHandler::handleDiagnostics(
+    const llvm::DiagnosticInfo &diag) {
+  if (const auto *optRemark =
+          dyn_cast<llvm::DiagnosticInfoOptimizationBase>(&diag)) {
+    remark::RemarkKind kind =
+        getRemarkKind(static_cast<llvm::DiagnosticKind>(optRemark->getKind()));
+    if (!engine ||
+        !engine->isRemarkEnabled(kind, getCategory(optRemark->getPassName())))
+      return false;
+    importLLVMRemark(*engine,
+                     resolveLocation(anchor, functionLocations, *optRemark),
+                     *optRemark);
+    return true;
+  }
+
+  std::string message;
+  llvm::raw_string_ostream os(message);
+  llvm::DiagnosticPrinterRawOStream printer(os);
+  diag.print(printer);
+  StringRef text = StringRef(message).rtrim();
+
+  Location loc = anchor->getLoc();
+  if (const auto *withLoc = dyn_cast<llvm::DiagnosticInfoUnsupported>(&diag)) {
+    loc = resolveLocation(anchor, functionLocations, *withLoc);
+    // The location is carried by `loc` already.
+    text.consume_front(withLoc->getLocationStr() + ": ");
+  }
+
+  switch (diag.getSeverity()) {
+  case llvm::DS_Error:
+    emitError(loc) << text;
+    break;
+  case llvm::DS_Warning:
+    emitWarning(loc) << text;
+    break;
+  case llvm::DS_Remark:
+  case llvm::DS_Note:
+    emitRemark(loc) << text;
+    break;
+  }
+  return true;
+}
diff --git a/mlir/lib/Target/LLVM/CMakeLists.txt b/mlir/lib/Target/LLVM/CMakeLists.txt
index bd1d66d1e43af..d59138cd9db23 100644
--- a/mlir/lib/Target/LLVM/CMakeLists.txt
+++ b/mlir/lib/Target/LLVM/CMakeLists.txt
@@ -19,6 +19,7 @@ add_mlir_library(MLIRTargetLLVM
   Target
   LINK_LIBS PUBLIC
   MLIRExecutionEngineUtils
+  MLIRRemarkStreamer
   MLIRTargetLLVMIRExport
 )
 
diff --git a/mlir/lib/Target/LLVM/ModuleToObject.cpp b/mlir/lib/Target/LLVM/ModuleToObject.cpp
index 8eaf8d9cadcd2..0f43e9c384048 100644
--- a/mlir/lib/Target/LLVM/ModuleToObject.cpp
+++ b/mlir/lib/Target/LLVM/ModuleToObject.cpp
@@ -16,6 +16,7 @@
 #include "mlir/ExecutionEngine/OptUtils.h"
 #include "mlir/IR/BuiltinAttributeInterfaces.h"
 #include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/Remark/LLVMRemarkImport.h"
 #include "mlir/Target/LLVMIR/Export.h"
 #include "mlir/Target/LLVMIR/ModuleTranslation.h"
 
@@ -242,9 +243,16 @@ ModuleToObject::moduleToObject(llvm::Module &llvmModule) {
   return binaryData;
 }
 
+void ModuleToObject::setupLLVMContext(llvm::LLVMContext &llvmContext) {
+  llvmContext.setDiagnosticHandler(
+      std::make_unique<remark::LLVMToMLIRDiagnosticHandler>(&getOperation()),
+      /*RespectFilters=*/true);
+}
+
 std::optional<SmallVector<char, 0>> ModuleToObject::run() {
   // Translate the module to LLVM IR.
   llvm::LLVMContext llvmContext;
+  setupLLVMContext(llvmContext);
   std::unique_ptr<llvm::Module> llvmModule = translateToLLVMIR(llvmContext);
   if (!llvmModule) {
     getOperation().emitError() << "Fa...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/222300


More information about the Mlir-commits mailing list