mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-10-07 19:03:57 +00:00
[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:
parent
21765af763
commit
a014fadb2e
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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 ®istry) {
|
||||
// Register the DLTI dialect used to express the data layout
|
||||
|
@ -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()))
|
||||
|
@ -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]
|
||||
|
51
mlir/test/mlir-translate/import-diagnostics.ll
Normal file
51
mlir/test/mlir-translate/import-diagnostics.ll
Normal 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)
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user