-
Notifications
You must be signed in to change notification settings - Fork 254
Add support for debug macro information (DW_MACINFO_define/undef) #3562
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -66,6 +66,8 @@ void LLVMToSPIRVDbgTran::transDebugMetadata() { | |||||
| transDbgEntry(IE); | ||||||
| } | ||||||
|
|
||||||
| transDbgMacros(); | ||||||
|
|
||||||
| for (const DIType *T : DIF.types()) | ||||||
| transDbgEntry(T); | ||||||
|
|
||||||
|
|
@@ -1681,3 +1683,75 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgModule(const DIModule *Module) { | |||||
| BM->addCapability(spv::CapabilityDebugInfoModuleINTEL); | ||||||
| return BM->addDebugInfo(SPIRVDebug::ModuleINTEL, getVoidTy(), Ops); | ||||||
| } | ||||||
|
|
||||||
| void LLVMToSPIRVDbgTran::transDbgMacros() { | ||||||
| auto ProcessMacros = [&](unsigned MacroType, auto &&Handler) { | ||||||
| for (const auto &[Macro, MacroFile] : DIF.macros()) { | ||||||
| if (Macro->getMacinfoType() != MacroType) | ||||||
| continue; | ||||||
|
|
||||||
| SPIRVString *FileName = BM->getString(""); | ||||||
| if (MacroFile && MacroFile->getFile()) | ||||||
| FileName = BM->getString(getFullPath(MacroFile->getFile())); | ||||||
|
|
||||||
| Handler(Macro, FileName); | ||||||
| } | ||||||
| }; | ||||||
|
|
||||||
| // Process DW_MACINFO_define macros and populate MacroDefMap | ||||||
| ProcessMacros(dwarf::DW_MACINFO_define, | ||||||
| [&](const DIMacro *Macro, SPIRVString *FileName) { | ||||||
| transDbgMacroDefine(Macro, FileName); | ||||||
| }); | ||||||
|
|
||||||
| // Process DW_MACINFO_undef macros (after DW_MACINFO_define populates | ||||||
| // MacroDefMap). DebugMacroUndef in SPIR-V requires a reference to the | ||||||
| // DebugMacroDef (not just the macro name as in LLVM IR) | ||||||
| ProcessMacros(dwarf::DW_MACINFO_undef, | ||||||
| [&](const DIMacro *Macro, SPIRVString *FileName) { | ||||||
| transDbgMacroUndef(Macro, FileName); | ||||||
| }); | ||||||
| } | ||||||
|
|
||||||
| SPIRVEntry *LLVMToSPIRVDbgTran::transDbgMacroDefine(const DIMacro *Macro, | ||||||
| SPIRVString *FileName) { | ||||||
| SPIRVWordVec Ops; | ||||||
| using namespace SPIRVDebug::Operand::MacroDef; | ||||||
| Ops.resize(OperandCount); | ||||||
| Ops[SourceIdx] = FileName->getId(); | ||||||
| Ops[LineIdx] = | ||||||
| SPIRVWriter->transValue(getUInt(M, Macro->getLine()), nullptr)->getId(); | ||||||
| Ops[NameIdx] = BM->getString(Macro->getName().str())->getId(); | ||||||
| Ops[ValueIdx] = BM->getString(Macro->getValue().str())->getId(); | ||||||
|
|
||||||
| SPIRVEntry *MacroEntry = | ||||||
| BM->addDebugInfo(SPIRVDebug::MacroDef, getVoidTy(), Ops); | ||||||
| MDMap[Macro] = MacroEntry; | ||||||
| MacroDefMap[Macro->getName().str()] = static_cast<SPIRVExtInst *>(MacroEntry); | ||||||
| return MacroEntry; | ||||||
| } | ||||||
|
|
||||||
| SPIRVEntry *LLVMToSPIRVDbgTran::transDbgMacroUndef(const DIMacro *Macro, | ||||||
| SPIRVString *FileName) { | ||||||
| SPIRVWordVec Ops; | ||||||
| using namespace SPIRVDebug::Operand::MacroUndef; | ||||||
| Ops.resize(OperandCount); | ||||||
| Ops[SourceIdx] = FileName->getId(); | ||||||
| Ops[LineIdx] = | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same than above. |
||||||
| SPIRVWriter->transValue(getUInt(M, Macro->getLine()), nullptr)->getId(); | ||||||
|
|
||||||
| SPIRVId MacroDefId = getDebugInfoNoneId(); | ||||||
|
|
||||||
| // transDbgMacroDefine is processed first so MacroDefMap is already populated | ||||||
| // at this point | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| auto It = MacroDefMap.find(Macro->getName().str()); | ||||||
| if (It != MacroDefMap.end()) { | ||||||
| MacroDefId = It->second->getId(); | ||||||
| } | ||||||
|
|
||||||
| Ops[MacroIdx] = MacroDefId; | ||||||
| SPIRVEntry *MacroEntry = | ||||||
| BM->addDebugInfo(SPIRVDebug::MacroUndef, getVoidTy(), Ops); | ||||||
| MDMap[Macro] = MacroEntry; | ||||||
| return MacroEntry; | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| ; Test round-trip translation of debug macro information: | ||
| ; LLVM IR -> SPIR-V -> LLVM IR | ||
|
|
||
| ; RUN: llvm-spirv --spirv-debug-info-version=nonsemantic-shader-100 %s -o %t.spv | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Note, that the spec links in the PR description are leading to OpenCL.DebugInfo.100 instruction set, while: I'd suggest to test and implement all 3 debug information types: OpenCL, nonsemantic.100 and nonsemantic.200. The later 2 are identical for Macro handling. OpenCL is a bit different, but not that drastically: see the following lines here and there which transforms literals to constants:
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks, will do. |
||
| ; RUN: spirv-val %t.spv | ||
|
|
||
| ; RUN: llvm-spirv -r %t.spv -o %t.rev.bc | ||
| ; RUN: llvm-dis %t.rev.bc -o %t.rev.ll | ||
| ; RUN: FileCheck %s --input-file %t.rev.ll --check-prefix CHECK | ||
|
|
||
| ; CHECK-DAG: ![[#r1:]] = !DIFile(filename: "def.c", directory: ".") | ||
| ; CHECK-DAG: ![[#r2:]] = !DIMacroFile(file: ![[#r1]], nodes: ![[#r3:]]) | ||
| ; CHECK-DAG: ![[#r3]] = !{![[#r4:]], ![[#r5:]]} | ||
| ; CHECK-DAG: ![[#r4]] = !DIMacro(type: DW_MACINFO_define, line: 1, name: "SIZE", value: "5") | ||
| ; CHECK-DAG: ![[#r5]] = !DIMacro(type: DW_MACINFO_undef, line: 1, name: "SIZE") | ||
|
|
||
| target triple = "spir64-unknown-unknown" | ||
|
|
||
| ; Function Attrs: nounwind | ||
| define spir_func i32 @main() #0 { | ||
| entry: | ||
| ret i32 0 | ||
| } | ||
|
|
||
| attributes #0 = { nounwind } | ||
|
|
||
| !llvm.module.flags = !{!0, !1, !12} | ||
| !llvm.dbg.cu = !{!4} | ||
| !spirv.MemoryModel = !{!13} | ||
| !opencl.enable.FP_CONTRACT = !{} | ||
| !spirv.Source = !{!14} | ||
| !opencl.spir.version = !{!15} | ||
| !opencl.used.extensions = !{!16} | ||
| !opencl.used.optional.core.features = !{!16} | ||
| !spirv.Generator = !{!17} | ||
|
|
||
| !0 = !{i32 7, !"Dwarf Version", i32 0} | ||
| !1 = !{i32 2, !"Source Lang Literal", !2} | ||
| !2 = !{!3} | ||
| !3 = !{!4, i32 12} | ||
| !4 = distinct !DICompileUnit(language: DW_LANG_OpenCL, file: !5, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, macros: !6) | ||
| !5 = !DIFile(filename: "def.c", directory: "/tmp") | ||
| !6 = !{!7} | ||
| !7 = !DIMacroFile(file: !8, nodes: !9) | ||
| !8 = !DIFile(filename: "def.c", directory: ".") | ||
| !9 = !{!10, !11} | ||
| !10 = !DIMacro(type: DW_MACINFO_define, line: 1, name: "SIZE", value: "5") | ||
| !11 = !DIMacro(type: DW_MACINFO_undef, line: 1, name: "SIZE") | ||
| !12 = !{i32 2, !"Debug Info Version", i32 3} | ||
| !13 = !{i32 2, i32 2} | ||
| !14 = !{i32 4, i32 100000} | ||
| !15 = !{i32 1, i32 2} | ||
| !16 = !{} | ||
| !17 = !{i16 7, i16 0} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| ; This test exercises the case where the DICompileUnit has as !DIMacro without a DIMacroFile | ||
|
|
||
| ; Test round-trip translation of debug macro information: | ||
| ; LLVM IR -> SPIR-V -> LLVM IR | ||
|
|
||
| ; RUN: llvm-spirv --spirv-debug-info-version=nonsemantic-shader-100 %s -o %t.spv | ||
| ; RUN: spirv-val %t.spv | ||
|
|
||
| ; RUN: llvm-spirv -r %t.spv -o %t.rev.bc | ||
| ; RUN: llvm-dis %t.rev.bc -o %t.rev.ll | ||
| ; RUN: FileCheck %s --input-file %t.rev.ll | ||
|
|
||
| ; CHECK-NOT: !DIMacroFile | ||
| ; CHECK-DAG: !DIMacro(type: DW_MACINFO_define, line: 1, name: "SIZE", value: "5") | ||
|
|
||
| target triple = "spir64-unknown-unknown" | ||
|
|
||
| ; Function Attrs: nounwind | ||
| define spir_func i32 @main() #0 { | ||
| entry: | ||
| ret i32 0 | ||
| } | ||
|
|
||
| attributes #0 = { nounwind } | ||
|
|
||
| !llvm.module.flags = !{!0, !1, !12} | ||
| !llvm.dbg.cu = !{!4} | ||
| !spirv.MemoryModel = !{!13} | ||
| !opencl.enable.FP_CONTRACT = !{} | ||
| !spirv.Source = !{!14} | ||
| !opencl.spir.version = !{!15} | ||
| !opencl.used.extensions = !{!16} | ||
| !opencl.used.optional.core.features = !{!16} | ||
| !spirv.Generator = !{!17} | ||
|
|
||
| !0 = !{i32 7, !"Dwarf Version", i32 0} | ||
| !1 = !{i32 2, !"Source Lang Literal", !2} | ||
| !2 = !{!3} | ||
| !3 = !{!4, i32 12} | ||
| !4 = distinct !DICompileUnit(language: DW_LANG_OpenCL, file: !5, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, macros: !6) | ||
| !5 = !DIFile(filename: "def.c", directory: "/tmp") | ||
| !6 = !{!10} | ||
| !10 = !DIMacro(type: DW_MACINFO_define, line: 1, name: "SIZE", value: "5") | ||
| !12 = !{i32 2, !"Debug Info Version", i32 3} | ||
| !13 = !{i32 2, i32 2} | ||
| !14 = !{i32 4, i32 100000} | ||
| !15 = !{i32 1, i32 2} | ||
| !16 = !{} | ||
| !17 = !{i16 7, i16 0} | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm looking correctly at the spec,
Lineis a literal number, not an<id>.