diff --git a/mlir/include/mlir/Target/LLVMIR/Import.h b/mlir/include/mlir/Target/LLVMIR/Import.h --- a/mlir/include/mlir/Target/LLVMIR/Import.h +++ b/mlir/include/mlir/Target/LLVMIR/Import.h @@ -34,10 +34,12 @@ /// 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 translateLLVMIRToModule(std::unique_ptr llvmModule, - MLIRContext *context); + MLIRContext *context, + bool emitExpensiveWarnings = true); /// Translate the given LLVM data layout into an MLIR equivalent using the DLTI /// dialect. diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h --- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h +++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h @@ -45,7 +45,8 @@ /// that are introduced at the beginning of the region. class ModuleImport { public: - ModuleImport(ModuleOp mlirModule, std::unique_ptr llvmModule); + ModuleImport(ModuleOp mlirModule, std::unique_ptr 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 @@ std::unique_ptr debugImporter; /// Loop annotation importer. std::unique_ptr 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 diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp --- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp +++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp @@ -25,6 +25,12 @@ namespace mlir { void registerFromLLVMIRTranslation() { + static llvm::cl::opt 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 @@ } if (llvm::verifyModule(*llvmModule, &llvm::errs())) return nullptr; - return translateLLVMIRToModule(std::move(llvmModule), context); + + return translateLLVMIRToModule(std::move(llvmModule), context, + emitExpensiveWarnings); }, [](DialectRegistry ®istry) { // Register the DLTI dialect used to express the data layout diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -153,14 +153,16 @@ } ModuleImport::ModuleImport(ModuleOp mlirModule, - std::unique_ptr llvmModule) + std::unique_ptr 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(mlirModule)), loopAnnotationImporter( - std::make_unique(*this, builder)) { + std::make_unique(*this, builder)), + emitExpensiveWarnings(emitExpensiveWarnings) { builder.setInsertionPointToStart(mlirModule.getBody()); } @@ -619,10 +621,12 @@ 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 @@ 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 @@ OwningOpRef mlir::translateLLVMIRToModule(std::unique_ptr 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 @@ assert(llvm::is_contained(context->getAvailableDialects(), DLTIDialect::getDialectNamespace())); context->loadAllAvailableDialects(); - OwningOpRef 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())) diff --git a/mlir/test/Target/LLVMIR/Import/import-failure.ll b/mlir/test/Target/LLVMIR/Import/import-failure.ll --- a/mlir/test/Target/LLVMIR/Import/import-failure.ll +++ b/mlir/test/Target/LLVMIR/Import/import-failure.ll @@ -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] diff --git a/mlir/test/mlir-translate/import-diagnostics.ll b/mlir/test/mlir-translate/import-diagnostics.ll new file mode 100644 --- /dev/null +++ b/mlir/test/mlir-translate/import-diagnostics.ll @@ -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) diff --git a/mlir/test/mlir-translate/import-error-only.ll b/mlir/test/mlir-translate/import-error-only.ll deleted file mode 100644 --- a/mlir/test/mlir-translate/import-error-only.ll +++ /dev/null @@ -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 -}