[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