Skip to content

Commit 090d03d

Browse files
authored
[MLIR][LLVM] Add flag to skip import of DICompositeType's elems (#89355)
This commit introduces a flag to allow skipping the potentially recursive import of DICompositeType elements. This patch is essentially a bandaid for the still broken recursive debug type import. Some of our downstream inputs are produced by excessive usage of template meta programming, and thus contain tens of thousands of types that all participate in such recursions. Unfortunately, the series of patches that introduces type support is not easily revertible due to being around for a while now and Modular depending on it. We can consider to revert this change once the type importer has show to be very performant, but for now we are talking second vs hours to import specific files.
1 parent b3c72bc commit 090d03d

File tree

7 files changed

+65
-18
lines changed

7 files changed

+65
-18
lines changed

mlir/include/mlir/Target/LLVMIR/Import.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
#define MLIR_TARGET_LLVMIR_IMPORT_H
1515

1616
#include "mlir/IR/OwningOpRef.h"
17-
#include "mlir/Support/LLVM.h"
18-
#include "llvm/ADT/StringRef.h"
1917
#include <memory>
2018

2119
// Forward-declare LLVM classes.
@@ -34,12 +32,17 @@ class ModuleOp;
3432
/// The translation supports operations from any dialect that has a registered
3533
/// implementation of the LLVMImportDialectInterface. It returns nullptr if the
3634
/// translation fails and reports errors using the error handler registered with
37-
/// the MLIR context. The `emitExpensiveWarnings` option controls if expensive
35+
/// the MLIR context.
36+
/// The `emitExpensiveWarnings` option controls if expensive
3837
/// but uncritical diagnostics should be emitted.
38+
/// The `dropDICompositeTypeElements` option controls if DICompositeTypes should
39+
/// be imported without elements. If set, the option avoids the recursive
40+
/// traversal of composite type debug information, which can be expensive for
41+
/// adversarial inputs.
3942
OwningOpRef<ModuleOp>
4043
translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
41-
MLIRContext *context,
42-
bool emitExpensiveWarnings = true);
44+
MLIRContext *context, bool emitExpensiveWarnings = true,
45+
bool dropDICompositeTypeElements = false);
4346

4447
/// Translate the given LLVM data layout into an MLIR equivalent using the DLTI
4548
/// dialect.

mlir/include/mlir/Target/LLVMIR/ModuleImport.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class LoopAnnotationImporter;
4747
class ModuleImport {
4848
public:
4949
ModuleImport(ModuleOp mlirModule, std::unique_ptr<llvm::Module> llvmModule,
50-
bool emitExpensiveWarnings);
50+
bool emitExpensiveWarnings, bool importEmptyDICompositeTypes);
5151

5252
/// Calls the LLVMImportInterface initialization that queries the registered
5353
/// dialect interfaces for the supported LLVM IR intrinsics and metadata kinds

mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ void registerFromLLVMIRTranslation() {
3030
llvm::cl::desc("Emit expensive warnings during LLVM IR import "
3131
"(discouraged: testing only!)"),
3232
llvm::cl::init(false));
33+
static llvm::cl::opt<bool> dropDICompositeTypeElements(
34+
"drop-di-composite-type-elements",
35+
llvm::cl::desc(
36+
"Avoid translating the elements of DICompositeTypes during "
37+
"the LLVM IR import (discouraged: testing only!)"),
38+
llvm::cl::init(false));
3339

3440
TranslateToMLIRRegistration registration(
3541
"import-llvm", "Translate LLVMIR to MLIR",
@@ -51,7 +57,8 @@ void registerFromLLVMIRTranslation() {
5157
return nullptr;
5258

5359
return translateLLVMIRToModule(std::move(llvmModule), context,
54-
emitExpensiveWarnings);
60+
emitExpensiveWarnings,
61+
dropDICompositeTypeElements);
5562
},
5663
[](DialectRegistry &registry) {
5764
// Register the DLTI dialect used to express the data layout

mlir/lib/Target/LLVMIR/DebugImporter.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ using namespace mlir;
2626
using namespace mlir::LLVM;
2727
using namespace mlir::LLVM::detail;
2828

29-
DebugImporter::DebugImporter(ModuleOp mlirModule)
29+
DebugImporter::DebugImporter(ModuleOp mlirModule,
30+
bool dropDICompositeTypeElements)
3031
: recursionPruner(mlirModule.getContext()),
31-
context(mlirModule.getContext()), mlirModule(mlirModule) {}
32+
context(mlirModule.getContext()), mlirModule(mlirModule),
33+
dropDICompositeTypeElements(dropDICompositeTypeElements) {}
3234

3335
Location DebugImporter::translateFuncLocation(llvm::Function *func) {
3436
llvm::DISubprogram *subprogram = func->getSubprogram();
@@ -69,9 +71,11 @@ DICompileUnitAttr DebugImporter::translateImpl(llvm::DICompileUnit *node) {
6971
DICompositeTypeAttr DebugImporter::translateImpl(llvm::DICompositeType *node) {
7072
std::optional<DIFlags> flags = symbolizeDIFlags(node->getFlags());
7173
SmallVector<DINodeAttr> elements;
72-
for (llvm::DINode *element : node->getElements()) {
73-
assert(element && "expected a non-null element type");
74-
elements.push_back(translate(element));
74+
if (!dropDICompositeTypeElements) {
75+
for (llvm::DINode *element : node->getElements()) {
76+
assert(element && "expected a non-null element type");
77+
elements.push_back(translate(element));
78+
}
7579
}
7680
// Drop the elements parameter if any of the elements are invalid.
7781
if (llvm::is_contained(elements, nullptr))

mlir/lib/Target/LLVMIR/DebugImporter.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ namespace detail {
2929

3030
class DebugImporter {
3131
public:
32-
DebugImporter(ModuleOp mlirModule);
32+
DebugImporter(ModuleOp mlirModule, bool dropDICompositeTypeElements);
3333

3434
/// Translates the given LLVM debug location to an MLIR location.
3535
Location translateLoc(llvm::DILocation *loc);
@@ -184,6 +184,12 @@ class DebugImporter {
184184

185185
MLIRContext *context;
186186
ModuleOp mlirModule;
187+
188+
/// An option to control if DICompositeTypes should always be imported without
189+
/// converting their elements. If set, the option avoids the recursive
190+
/// traversal of composite type debug information, which can be expensive for
191+
/// adversarial inputs.
192+
bool dropDICompositeTypeElements;
187193
};
188194

189195
} // namespace detail

mlir/lib/Target/LLVMIR/ModuleImport.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,14 @@ getTopologicallySortedBlocks(ArrayRef<llvm::BasicBlock *> basicBlocks) {
155155

156156
ModuleImport::ModuleImport(ModuleOp mlirModule,
157157
std::unique_ptr<llvm::Module> llvmModule,
158-
bool emitExpensiveWarnings)
158+
bool emitExpensiveWarnings,
159+
bool importEmptyDICompositeTypes)
159160
: builder(mlirModule->getContext()), context(mlirModule->getContext()),
160161
mlirModule(mlirModule), llvmModule(std::move(llvmModule)),
161162
iface(mlirModule->getContext()),
162163
typeTranslator(*mlirModule->getContext()),
163-
debugImporter(std::make_unique<DebugImporter>(mlirModule)),
164+
debugImporter(std::make_unique<DebugImporter>(
165+
mlirModule, importEmptyDICompositeTypes)),
164166
loopAnnotationImporter(
165167
std::make_unique<LoopAnnotationImporter>(*this, builder)),
166168
emitExpensiveWarnings(emitExpensiveWarnings) {
@@ -2092,8 +2094,8 @@ ModuleImport::translateLoopAnnotationAttr(const llvm::MDNode *node,
20922094

20932095
OwningOpRef<ModuleOp>
20942096
mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
2095-
MLIRContext *context,
2096-
bool emitExpensiveWarnings) {
2097+
MLIRContext *context, bool emitExpensiveWarnings,
2098+
bool dropDICompositeTypeElements) {
20972099
// Preload all registered dialects to allow the import to iterate the
20982100
// registered LLVMImportDialectInterface implementations and query the
20992101
// supported LLVM IR constructs before starting the translation. Assumes the
@@ -2109,7 +2111,7 @@ mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
21092111
/*column=*/0)));
21102112

21112113
ModuleImport moduleImport(module.get(), std::move(llvmModule),
2112-
emitExpensiveWarnings);
2114+
emitExpensiveWarnings, dropDICompositeTypeElements);
21132115
if (failed(moduleImport.initializeImportInterface()))
21142116
return {};
21152117
if (failed(moduleImport.convertDataLayout()))
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
; RUN: mlir-translate -import-llvm -mlir-print-debuginfo -split-input-file -drop-di-composite-type-elements %s | FileCheck %s
2+
3+
; Verifies that the according flag avoids the conversion of the elements of the
4+
; DICompositeType.
5+
6+
; CHECK-NOT: di_derive_type
7+
; CHECK: #{{.+}} = #llvm.di_composite_type<tag = DW_TAG_class_type, name = "class">
8+
; CHECK-NOT: di_derive_type
9+
10+
define void @composite_type() !dbg !3 {
11+
ret void
12+
}
13+
14+
!llvm.dbg.cu = !{!1}
15+
!llvm.module.flags = !{!0}
16+
!0 = !{i32 2, !"Debug Info Version", i32 3}
17+
!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
18+
!2 = !DIFile(filename: "debug-info.ll", directory: "/")
19+
!3 = distinct !DISubprogram(name: "composite_type", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1, type: !4)
20+
!4 = !DISubroutineType(types: !5)
21+
!5 = !{!6}
22+
!6 = !DICompositeType(tag: DW_TAG_class_type, name: "class", elements: !7)
23+
!7 = !{!9}
24+
!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, flags: DIFlagArtificial | DIFlagObjectPointer)
25+
!9 = !DIDerivedType(tag: DW_TAG_member, name: "call_field", file: !2, baseType: !8)

0 commit comments

Comments
 (0)