[mlir] Avoid expensive LLVM IR import warnings

The revision adds a flag to the LLVM IR import
that avoids emitting expensive warnings about
unsupported debug intrinsics and unhandled
metadata.

Reviewed By: Dinistro

Differential Revision: https://reviews.llvm.org/D153625
This commit is contained in:
Tobias Gysi 2023-06-26 06:40:02 +00:00
parent 21765af763
commit a014fadb2e
7 changed files with 90 additions and 43 deletions

View File

@ -34,10 +34,12 @@ class ModuleOp;
/// The translation supports operations from any dialect that has a registered
/// implementation of the LLVMImportDialectInterface. It returns nullptr if the
/// translation fails and reports errors using the error handler registered with
/// the MLIR context.
/// the MLIR context. The `emitExpensiveWarnings` option controls if expensive
/// but uncritical diagnostics should be emitted.
OwningOpRef<ModuleOp>
translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
MLIRContext *context);
MLIRContext *context,
bool emitExpensiveWarnings = true);
/// Translate the given LLVM data layout into an MLIR equivalent using the DLTI
/// dialect.

View File

@ -45,7 +45,8 @@ class LoopAnnotationImporter;
/// that are introduced at the beginning of the region.
class ModuleImport {
public:
ModuleImport(ModuleOp mlirModule, std::unique_ptr<llvm::Module> llvmModule);
ModuleImport(ModuleOp mlirModule, std::unique_ptr<llvm::Module> llvmModule,
bool emitExpensiveWarnings);
/// Calls the LLVMImportInterface initialization that queries the registered
/// dialect interfaces for the supported LLVM IR intrinsics and metadata kinds
@ -353,6 +354,11 @@ private:
std::unique_ptr<detail::DebugImporter> debugImporter;
/// Loop annotation importer.
std::unique_ptr<detail::LoopAnnotationImporter> loopAnnotationImporter;
/// An option to control if expensive but uncritical diagnostics should be
/// emitted. Avoids generating warnings for unhandled debug intrinsics and
/// metadata that otherwise dominate the translation time for large inputs.
bool emitExpensiveWarnings;
};
} // namespace LLVM

View File

@ -25,6 +25,12 @@ using namespace mlir;
namespace mlir {
void registerFromLLVMIRTranslation() {
static llvm::cl::opt<bool> emitExpensiveWarnings(
"emit-expensive-warnings",
llvm::cl::desc("Emit expensive warnings during LLVM IR import "
"(discouraged: testing only!)"),
llvm::cl::init(false));
TranslateToMLIRRegistration registration(
"import-llvm", "Translate LLVMIR to MLIR",
[](llvm::SourceMgr &sourceMgr,
@ -43,7 +49,9 @@ void registerFromLLVMIRTranslation() {
}
if (llvm::verifyModule(*llvmModule, &llvm::errs()))
return nullptr;
return translateLLVMIRToModule(std::move(llvmModule), context);
return translateLLVMIRToModule(std::move(llvmModule), context,
emitExpensiveWarnings);
},
[](DialectRegistry &registry) {
// Register the DLTI dialect used to express the data layout

View File

@ -153,14 +153,16 @@ getTopologicallySortedBlocks(llvm::Function *func) {
}
ModuleImport::ModuleImport(ModuleOp mlirModule,
std::unique_ptr<llvm::Module> llvmModule)
std::unique_ptr<llvm::Module> llvmModule,
bool emitExpensiveWarnings)
: builder(mlirModule->getContext()), context(mlirModule->getContext()),
mlirModule(mlirModule), llvmModule(std::move(llvmModule)),
iface(mlirModule->getContext()),
typeTranslator(*mlirModule->getContext()),
debugImporter(std::make_unique<DebugImporter>(mlirModule)),
loopAnnotationImporter(
std::make_unique<LoopAnnotationImporter>(*this, builder)) {
std::make_unique<LoopAnnotationImporter>(*this, builder)),
emitExpensiveWarnings(emitExpensiveWarnings) {
builder.setInsertionPointToStart(mlirModule.getBody());
}
@ -619,10 +621,12 @@ void ModuleImport::setNonDebugMetadataAttrs(llvm::Instruction *inst,
if (!iface.isConvertibleMetadata(kind))
continue;
if (failed(iface.setMetadataAttrs(builder, kind, node, op, *this))) {
Location loc = debugImporter->translateLoc(inst->getDebugLoc());
emitWarning(loc) << "unhandled metadata: "
<< diagMD(node, llvmModule.get()) << " on "
<< diag(*inst);
if (emitExpensiveWarnings) {
Location loc = debugImporter->translateLoc(inst->getDebugLoc());
emitWarning(loc) << "unhandled metadata: "
<< diagMD(node, llvmModule.get()) << " on "
<< diag(*inst);
}
}
}
}
@ -1783,8 +1787,10 @@ LogicalResult ModuleImport::processBasicBlock(llvm::BasicBlock *bb,
if (Operation *op = lookupOperation(&inst)) {
setNonDebugMetadataAttrs(&inst, op);
} else if (inst.getOpcode() != llvm::Instruction::PHI) {
Location loc = debugImporter->translateLoc(inst.getDebugLoc());
emitWarning(loc) << "dropped instruction: " << diag(inst);
if (emitExpensiveWarnings) {
Location loc = debugImporter->translateLoc(inst.getDebugLoc());
emitWarning(loc) << "dropped instruction: " << diag(inst);
}
}
}
return success();
@ -1803,7 +1809,8 @@ ModuleImport::translateLoopAnnotationAttr(const llvm::MDNode *node,
OwningOpRef<ModuleOp>
mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
MLIRContext *context) {
MLIRContext *context,
bool emitExpensiveWarnings) {
// Preload all registered dialects to allow the import to iterate the
// registered LLVMImportDialectInterface implementations and query the
// supported LLVM IR constructs before starting the translation. Assumes the
@ -1814,12 +1821,12 @@ mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
assert(llvm::is_contained(context->getAvailableDialects(),
DLTIDialect::getDialectNamespace()));
context->loadAllAvailableDialects();
OwningOpRef<ModuleOp> module(ModuleOp::create(FileLineColLoc::get(
StringAttr::get(context, llvmModule->getSourceFileName()), /*line=*/0,
/*column=*/0)));
ModuleImport moduleImport(module.get(), std::move(llvmModule));
ModuleImport moduleImport(module.get(), std::move(llvmModule),
emitExpensiveWarnings);
if (failed(moduleImport.initializeImportInterface()))
return {};
if (failed(moduleImport.convertDataLayout()))

View File

@ -1,4 +1,4 @@
; RUN: not mlir-translate -import-llvm -split-input-file %s 2>&1 | FileCheck %s
; RUN: not mlir-translate -import-llvm -emit-expensive-warnings -split-input-file %s 2>&1 | FileCheck %s
; CHECK: import-failure.ll
; CHECK-SAME: error: unhandled instruction: indirectbr ptr %dst, [label %bb1, label %bb2]

View File

@ -0,0 +1,51 @@
; RUN: not mlir-translate %s -import-llvm -split-input-file -error-diagnostics-only 2>&1 | FileCheck %s --check-prefix=ERROR
; RUN: not mlir-translate %s -import-llvm -split-input-file 2>&1 | FileCheck %s --check-prefix=DEFAULT
; RUN: not mlir-translate %s -import-llvm -split-input-file -emit-expensive-warnings 2>&1 | FileCheck %s --check-prefix=EXPENSIVE
; ERROR-NOT: warning:
; DEFAULT: warning:
; EXPENSIVE: warning:
define void @warning(i64 %n, ptr %A) {
entry:
br label %end, !llvm.loop !0
end:
ret void
}
!0 = distinct !{!0, !1, !2}
!1 = !{!"llvm.loop.disable_nonforced"}
!2 = !{!"llvm.loop.typo"}
; // -----
; ERROR: error:
; DEFAULT: error:
; EXPENSIVE: error:
define i32 @error(ptr %dst) {
indirectbr ptr %dst, [label %bb1, label %bb2]
bb1:
ret i32 0
bb2:
ret i32 1
}
; // -----
declare void @llvm.dbg.value(metadata, metadata, metadata)
; ERROR-NOT: warning:
; DEFAULT-NOT: warning:
; EXPENSIVE: warning:
define void @dropped_instruction(i64 %arg1) {
call void @llvm.dbg.value(metadata i64 %arg1, metadata !3, metadata !DIExpression(DW_OP_plus_uconst, 42, DW_OP_stack_value)), !dbg !5
ret void
}
!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!0}
!0 = !{i32 2, !"Debug Info Version", i32 3}
!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
!2 = !DIFile(filename: "import-failure.ll", directory: "/")
!3 = !DILocalVariable(scope: !4, name: "arg1", file: !2, line: 1, arg: 1, align: 64);
!4 = distinct !DISubprogram(name: "intrinsic", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1)
!5 = !DILocation(line: 1, column: 2, scope: !4)

View File

@ -1,27 +0,0 @@
; RUN: not mlir-translate %s -import-llvm -split-input-file -error-diagnostics-only 2>&1 | FileCheck %s --check-prefix=ERROR
; RUN: not mlir-translate %s -import-llvm -split-input-file 2>&1 | FileCheck %s --check-prefix=ALL
; ERROR-NOT: warning:
; ALL: warning:
define void @warning(i64 %n, ptr %A) {
entry:
br label %end, !llvm.loop !0
end:
ret void
}
!0 = distinct !{!0, !1, !2}
!1 = !{!"llvm.loop.disable_nonforced"}
!2 = !{!"llvm.loop.typo"}
; // -----
; ERROR: error:
; ALL: error:
define i32 @error(ptr %dst) {
indirectbr ptr %dst, [label %bb1, label %bb2]
bb1:
ret i32 0
bb2:
ret i32 1
}