Skip to content

Commit 2b3a2f3

Browse files
authored
Implement SPV_INTEL_debug_module extension (#1089)
* Implement SPV_INTEL_debug_module extension Spec intel/llvm#3976
1 parent a84f589 commit 2b3a2f3

14 files changed

+308
-6
lines changed

include/LLVMSPIRVExtensions.inc

+1
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ EXT(SPV_INTEL_fpga_dsp_control)
4040
EXT(SPV_INTEL_memory_access_aliasing)
4141
EXT(SPV_INTEL_fpga_invocation_pipelining_attributes)
4242
EXT(SPV_INTEL_token_type)
43+
EXT(SPV_INTEL_debug_module)

lib/SPIRV/LLVMToSPIRVDbgTran.cpp

+27-3
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,12 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgEntryImpl(const MDNode *MDN) {
343343
case dwarf::DW_TAG_imported_declaration:
344344
return transDbgImportedEntry(cast<DIImportedEntity>(DIEntry));
345345

346+
case dwarf::DW_TAG_module: {
347+
if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_debug_module))
348+
return transDbgModule(cast<DIModule>(DIEntry));
349+
return getDebugInfoNone();
350+
}
351+
346352
default:
347353
return getDebugInfoNone();
348354
}
@@ -813,9 +819,10 @@ LLVMToSPIRVDbgTran::transDbgGlobalVariable(const DIGlobalVariable *GV) {
813819
// Parent scope
814820
DIScope *Context = GV->getScope();
815821
SPIRVEntry *Parent = SPIRVCU;
816-
// Global variable may be declared in scope of a namespace or it may be a
817-
// static variable declared in scope of a function
818-
if (Context && (isa<DINamespace>(Context) || isa<DISubprogram>(Context)))
822+
// Global variable may be declared in scope of a namespace or imported module,
823+
// it may also be a static variable declared in scope of a function.
824+
if (Context && (isa<DINamespace>(Context) || isa<DISubprogram>(Context) ||
825+
isa<DIModule>(Context)))
819826
Parent = transDbgEntry(Context);
820827
Ops[ParentIdx] = Parent->getId();
821828

@@ -1036,3 +1043,20 @@ LLVMToSPIRVDbgTran::transDbgImportedEntry(const DIImportedEntity *IE) {
10361043
Ops[ParentIdx] = getScope(IE->getScope())->getId();
10371044
return BM->addDebugInfo(SPIRVDebug::ImportedEntity, getVoidTy(), Ops);
10381045
}
1046+
1047+
SPIRVEntry *LLVMToSPIRVDbgTran::transDbgModule(const DIModule *Module) {
1048+
using namespace SPIRVDebug::Operand::ModuleINTEL;
1049+
SPIRVWordVec Ops(OperandCount);
1050+
Ops[NameIdx] = BM->getString(Module->getName().str())->getId();
1051+
Ops[SourceIdx] = getSource(Module->getFile())->getId();
1052+
Ops[LineIdx] = Module->getLineNo();
1053+
Ops[ParentIdx] = getScope(Module->getScope())->getId();
1054+
Ops[ConfigMacrosIdx] =
1055+
BM->getString(Module->getConfigurationMacros().str())->getId();
1056+
Ops[IncludePathIdx] = BM->getString(Module->getIncludePath().str())->getId();
1057+
Ops[ApiNotesIdx] = BM->getString(Module->getAPINotesFile().str())->getId();
1058+
Ops[IsDeclIdx] = Module->getIsDecl();
1059+
BM->addExtension(ExtensionID::SPV_INTEL_debug_module);
1060+
BM->addCapability(spv::internal::CapabilityDebugInfoModuleINTEL);
1061+
return BM->addDebugInfo(SPIRVDebug::ModuleINTEL, getVoidTy(), Ops);
1062+
}

lib/SPIRV/LLVMToSPIRVDbgTran.h

+3
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ class LLVMToSPIRVDbgTran {
143143
// Imported declarations and modules
144144
SPIRVEntry *transDbgImportedEntry(const DIImportedEntity *IE);
145145

146+
// A module in programming language. Example - Fortran module, clang module.
147+
SPIRVEntry *transDbgModule(const DIModule *IE);
148+
146149
SPIRVModule *BM;
147150
Module *M;
148151
LLVMToSPIRVBase *SPIRVWriter;

lib/SPIRV/SPIRVToLLVMDbgTran.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,8 @@ DINode *SPIRVToLLVMDbgTran::transImportedEntry(const SPIRVExtInst *DebugInst) {
783783
if (!Entity)
784784
return Builder.createImportedModule(
785785
Scope, static_cast<DIImportedEntity *>(nullptr), File, Line);
786+
if (DIModule *DM = dyn_cast<DIModule>(Entity))
787+
return Builder.createImportedModule(Scope, DM, File, Line);
786788
if (DIImportedEntity *IE = dyn_cast<DIImportedEntity>(Entity))
787789
return Builder.createImportedModule(Scope, IE, File, Line);
788790
if (DINamespace *NS = dyn_cast<DINamespace>(Entity))
@@ -799,6 +801,23 @@ DINode *SPIRVToLLVMDbgTran::transImportedEntry(const SPIRVExtInst *DebugInst) {
799801
llvm_unreachable("Unexpected kind of imported entity!");
800802
}
801803

804+
DINode *SPIRVToLLVMDbgTran::transModule(const SPIRVExtInst *DebugInst) {
805+
using namespace SPIRVDebug::Operand::ModuleINTEL;
806+
const SPIRVWordVec &Ops = DebugInst->getArguments();
807+
assert(Ops.size() >= OperandCount && "Invalid number of operands");
808+
DIScope *Scope = getScope(BM->getEntry(Ops[ParentIdx]));
809+
unsigned Line = Ops[LineIdx];
810+
DIFile *File = getFile(Ops[SourceIdx]);
811+
StringRef Name = getString(Ops[NameIdx]);
812+
StringRef ConfigMacros = getString(Ops[ConfigMacrosIdx]);
813+
StringRef IncludePath = getString(Ops[IncludePathIdx]);
814+
StringRef ApiNotes = getString(Ops[ApiNotesIdx]);
815+
bool IsDecl = Ops[IsDeclIdx];
816+
817+
return Builder.createModule(Scope, Name, ConfigMacros, IncludePath, ApiNotes,
818+
File, Line, IsDecl);
819+
}
820+
802821
MDNode *SPIRVToLLVMDbgTran::transExpression(const SPIRVExtInst *DebugInst) {
803822
const SPIRVWordVec &Args = DebugInst->getArguments();
804823
std::vector<int64_t> Ops;
@@ -895,6 +914,9 @@ MDNode *SPIRVToLLVMDbgTran::transDebugInstImpl(const SPIRVExtInst *DebugInst) {
895914
case SPIRVDebug::ImportedEntity:
896915
return transImportedEntry(DebugInst);
897916

917+
case SPIRVDebug::ModuleINTEL:
918+
return transModule(DebugInst);
919+
898920
case SPIRVDebug::Operation: // To be translated with transExpression
899921
case SPIRVDebug::Source: // To be used by other instructions
900922
return nullptr;

lib/SPIRV/SPIRVToLLVMDbgTran.h

+2
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ class SPIRVToLLVMDbgTran {
143143

144144
DINode *transImportedEntry(const SPIRVExtInst *DebugInst);
145145

146+
DINode *transModule(const SPIRVExtInst *DebugInst);
147+
146148
MDNode *transExpression(const SPIRVExtInst *DebugInst);
147149

148150
SPIRVModule *BM;

lib/SPIRV/libSPIRV/SPIRV.debug.h

+16-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ enum Instruction {
4848
MacroUndef = 33,
4949
ImportedEntity = 34,
5050
Source = 35,
51-
InstCount = 36
51+
ModuleINTEL = 36,
52+
InstCount = 37
5253
};
5354

5455
enum Flag {
@@ -770,6 +771,20 @@ enum {
770771
};
771772
}
772773

774+
namespace ModuleINTEL {
775+
enum {
776+
NameIdx = 0,
777+
SourceIdx = 1,
778+
LineIdx = 2,
779+
ParentIdx = 3,
780+
ConfigMacrosIdx = 4,
781+
IncludePathIdx = 5,
782+
ApiNotesIdx = 6,
783+
IsDeclIdx = 7,
784+
OperandCount = 8
785+
};
786+
}
787+
773788
} // namespace Operand
774789
} // namespace SPIRVDebug
775790

lib/SPIRV/libSPIRV/SPIRVExtInst.h

+1
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ template <> inline void SPIRVMap<SPIRVDebugExtOpKind, std::string>::init() {
253253
add(SPIRVDebug::NoScope, "DebugNoScope");
254254
add(SPIRVDebug::InlinedAt, "DebugInlinedAt");
255255
add(SPIRVDebug::ImportedEntity, "DebugImportedEntity");
256+
add(SPIRVDebug::ModuleINTEL, "DebugModuleINTEL");
256257
add(SPIRVDebug::Expression, "DebugExpression");
257258
add(SPIRVDebug::Operation, "DebugOperation");
258259
}

lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -571,8 +571,8 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
571571
add(internal::CapabilityFPGAInvocationPipeliningAttributesINTEL,
572572
"FPGAInvocationPipeliningAttributesINTEL");
573573
add(internal::CapabilityTokenTypeINTEL, "TokenTypeINTEL");
574-
575574
add(CapabilityMax, "Max");
575+
add(internal::CapabilityDebugInfoModuleINTEL, "DebugInfoModuleINTEL");
576576
}
577577
SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap)
578578

lib/SPIRV/libSPIRV/spirv_internal.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ enum InternalCapability {
5959
ICapFPGAInvocationPipeliningAttributesINTEL = 5916,
6060
ICapFastCompositeINTEL = 6093,
6161
ICapOptNoneINTEL = 6094,
62-
ICapTokenTypeINTEL = 6112
62+
ICapTokenTypeINTEL = 6112,
63+
ICapDebugInfoModuleINTEL = 6114
6364
};
6465

6566
enum InternalFunctionControlMask { IFunctionControlOptNoneINTELMask = 0x10000 };
@@ -108,6 +109,8 @@ constexpr Capability CapabilityFPGAInvocationPipeliningAttributesINTEL =
108109
static_cast<Capability>(ICapFPGAInvocationPipeliningAttributesINTEL);
109110
constexpr Capability CapabilityTokenTypeINTEL =
110111
static_cast<Capability>(ICapTokenTypeINTEL);
112+
constexpr Capability CapabilityDebugInfoModuleINTEL =
113+
static_cast<Capability>(ICapDebugInfoModuleINTEL);
111114

112115
constexpr FunctionControlMask FunctionControlOptNoneINTELMask =
113116
static_cast<FunctionControlMask>(IFunctionControlOptNoneINTELMask);

test/DebugInfo/DebugInfoNoneEntity.ll

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
; RUN: llvm-spirv %t.bc -o %t.spv
55
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
66

7+
; RUN: llvm-spirv -spirv-ext=+SPV_INTEL_debug_module %t.bc -o %t.spv
8+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
9+
710
source_filename = "llvm-link"
811
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
912
target triple = "spir64"

test/DebugInfo/X86/DIModule.ll

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
; ModuleID = '/Volumes/Data/apple-internal/llvm/tools/clang/test/Modules/debug-info-moduleimport.m'
2+
; RUN: llvm-as < %s -o %t.bc
3+
; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_debug_module %t.bc -o %t.spv
4+
; RUN: llvm-spirv -r %t.spv -o - | llvm-dis -o %t.ll
5+
6+
; RUN: llc -mtriple=x86_64-apple-macosx %t.ll -accel-tables=Dwarf -o %t -filetype=obj
7+
; RUN: llvm-dwarfdump -debug-info %t | FileCheck %s
8+
; RUN: llvm-dwarfdump -verify %t
9+
10+
; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_debug_module %t.bc -spirv-text -o - | FileCheck %s --check-prefix CHECK-SPIRV
11+
12+
; CHECK: DW_TAG_compile_unit
13+
; CHECK-NOT: DW_TAG
14+
; CHECK: DW_TAG_module
15+
; CHECK-NEXT: DW_AT_name {{.*}}"DebugModule"
16+
; CHECK-NEXT: DW_AT_LLVM_config_macros {{.*}}"-DMODULES=0"
17+
; CHECK-NEXT: DW_AT_LLVM_include_path {{.*}}"/llvm/tools/clang/test/Modules/Inputs"
18+
; CHECK-NEXT: DW_AT_LLVM_apinotes {{.*}}"m.apinotes"
19+
20+
; CHECK-SPIRV: Capability DebugInfoModuleINTEL
21+
; CHECK-SPIRV: Extension "SPV_INTEL_debug_module"
22+
23+
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
24+
target triple = "spir64-unknown-unknown"
25+
26+
; CHECK-SPIRV: String [[FileName:[0-9]+]] "/llvm/tools/clang/test/Modules/<stdin>"
27+
; CHECK-SPIRV: String [[EmptyStr:[0-9]+]] ""
28+
; CHECK-SPIRV: String [[Name:[0-9]+]] "DebugModule"
29+
; CHECK-SPIRV: String [[Defines:[0-9]+]] "-DMODULES=0"
30+
; CHECK-SPIRV: String [[IncludePath:[0-9]+]] "/llvm/tools/clang/test/Modules/Inputs"
31+
; CHECK-SPIRV: String [[ApiNotes:[0-9]+]] "m.apinotes"
32+
33+
; CHECK-SPIRV: ExtInst {{[0-9]+}} [[Module:[0-9]+]] {{[0-9]+}} DebugModuleINTEL [[Name]] {{[0-9]+}} 0 {{[0-9]+}} [[Defines]] [[IncludePath]] [[ApiNotes]] 0
34+
; CHECK-SPIRV: ExtInst {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} DebugImportedEntity {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} [[Module]]
35+
36+
!llvm.dbg.cu = !{!0}
37+
!llvm.module.flags = !{!6, !7}
38+
!llvm.ident = !{!8}
39+
40+
!0 = distinct !DICompileUnit(language: DW_LANG_ObjC, file: !1, producer: "LLVM version 3.7.0", isOptimized: false, runtimeVersion: 2, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !2, imports: !3, sysroot: "/")
41+
!1 = !DIFile(filename: "/llvm/tools/clang/test/Modules/<stdin>", directory: "/")
42+
!2 = !{}
43+
!3 = !{!4}
44+
!4 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !0, entity: !5, file: !1, line: 5)
45+
!5 = !DIModule(scope: null, name: "DebugModule", configMacros: "-DMODULES=0", includePath: "/llvm/tools/clang/test/Modules/Inputs", apinotes: "m.apinotes")
46+
!6 = !{i32 2, !"Dwarf Version", i32 4}
47+
!7 = !{i32 2, !"Debug Info Version", i32 3}
48+
!8 = !{!"LLVM version 3.7.0"}

test/DebugInfo/X86/DIModuleContext.ll

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; RUN: llvm-as < %s -o %t.bc
2+
; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_debug_module %t.bc -o %t.spv
3+
; RUN: llvm-spirv -r %t.spv -o - | llvm-dis -o %t.ll
4+
5+
; RUN: llc -mtriple=x86_64-apple-macosx %t.ll -o - -filetype=obj \
6+
; RUN: | llvm-dwarfdump -debug-info - | FileCheck %s
7+
; CHECK: DW_TAG_module
8+
; CHECK-NOT: NULL
9+
; CHECK: DW_TAG_structure_type
10+
11+
; Hand-crafted based on
12+
; struct s;
13+
; struct s *s;
14+
15+
source_filename = "test/DebugInfo/X86/DIModuleContext.ll"
16+
target triple = "spir64-unknown-unknown"
17+
18+
%struct.s = type opaque
19+
20+
@i = common addrspace(1) global %struct.s* null, align 8, !dbg !0
21+
22+
!llvm.dbg.cu = !{!2}
23+
!llvm.module.flags = !{!11, !12}
24+
25+
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
26+
!1 = !DIGlobalVariable(name: "s", scope: !2, file: !3, line: 2, type: !9, isLocal: false, isDefinition: true)
27+
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, imports: !6)
28+
!3 = !DIFile(filename: "test.c", directory: "/")
29+
!4 = !{}
30+
!5 = !{!0}
31+
!6 = !{!7}
32+
!7 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !2, entity: !8, file: !3, line: 11)
33+
!8 = !DIModule(scope: null, name: "Module", includePath: ".")
34+
!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64, align: 64)
35+
!10 = !DICompositeType(tag: DW_TAG_structure_type, name: "s", scope: !8, file: !3, line: 1, flags: DIFlagFwdDecl)
36+
!11 = !{i32 2, !"Dwarf Version", i32 2}
37+
!12 = !{i32 2, !"Debug Info Version", i32 3}
38+
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
; This test checks attributes of a Fortran module.
2+
; RUN: llvm-as < %s -o %t.bc
3+
; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_debug_module %t.bc -o %t.spv
4+
; RUN: llvm-spirv -r %t.spv -o - | llvm-dis -o %t.ll
5+
6+
; RUN: llc -mtriple=x86_64-unknown-linux-gnu %t.ll -filetype=obj -o - | \
7+
; RUN: llvm-dwarfdump - | FileCheck %s
8+
9+
; CHECK: DW_TAG_module
10+
; CHECK-NEXT: DW_AT_name ("dummy")
11+
; CHECK-NEXT: DW_AT_decl_file ("/fortran{{[/\\]}}module.f90")
12+
; CHECK-NEXT: DW_AT_decl_line (2)
13+
14+
; Generated from flang compiler, Fortran source to regenerate:
15+
; module dummy
16+
; integer :: foo
17+
; end module dummy
18+
19+
; ModuleID = '/tmp/module-b198fa.ll'
20+
source_filename = "/tmp/module-b198fa.ll"
21+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
22+
target triple = "spir64-unknown-unknown"
23+
24+
%struct_dummy_0_ = type <{ [4 x i8] }>
25+
26+
@_dummy_0_ = common addrspace(1) global %struct_dummy_0_ zeroinitializer, align 64, !dbg !0
27+
28+
; Function Attrs: noinline
29+
define float @dummy_() #0 {
30+
.L.entry:
31+
ret float undef
32+
}
33+
34+
attributes #0 = { noinline "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" }
35+
36+
!llvm.module.flags = !{!8, !9}
37+
!llvm.dbg.cu = !{!3}
38+
39+
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
40+
!1 = distinct !DIGlobalVariable(name: "foo", scope: !2, file: !4, type: !7, isLocal: false, isDefinition: true)
41+
!2 = !DIModule(scope: !3, name: "dummy", file: !4, line: 2)
42+
!3 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !4, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !5)
43+
!4 = !DIFile(filename: "module.f90", directory: "/fortran")
44+
!5 = !{}
45+
!6 = !{!0}
46+
!7 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed)
47+
!8 = !{i32 2, !"Dwarf Version", i32 4}
48+
!9 = !{i32 2, !"Debug Info Version", i32 3}

0 commit comments

Comments
 (0)