Skip to content

Commit 6c4a933

Browse files
MiloszSkobejkoigcbot
authored andcommitted
Fix DIStringType length emitting in DWARF (2nd try)
For some cases, there wasn't DW_AT_string_length added to variable, which resulted in treating vla array as character.
1 parent f8127f3 commit 6c4a933

File tree

5 files changed

+150
-13
lines changed

5 files changed

+150
-13
lines changed

IGC/DebugInfo/DwarfCompileUnit.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2044,8 +2044,22 @@ IGC::DIE *CompileUnit::constructVariableDIE(DbgVariable &DV, bool isScopeAbstrac
20442044
LLVM_DEBUG(dbgs() << "[DwarfDebug] constructing DIE for variable <" << Name << ">\n");
20452045
// Define variable debug information entry.
20462046
DIE *VariableDie = new DIE(DV.getTag());
2047+
2048+
// If variable is abstract or scope is abstract attributes should be
2049+
// applied immediately
20472050
DbgVariable *AbsVar = DV.getAbstractVariable();
20482051
DIE *AbsDIE = AbsVar ? AbsVar->getDIE() : NULL;
2052+
if (isScopeAbstract || AbsDIE) {
2053+
applyVariableAttributes(DV, VariableDie, isScopeAbstract, AbsDIE);
2054+
} else {
2055+
insertDIE(const_cast<DILocalVariable *>(DV.getVariable()), VariableDie);
2056+
}
2057+
return VariableDie;
2058+
}
2059+
2060+
void CompileUnit::applyVariableAttributes(DbgVariable &DV, DIE *VariableDie, bool isScopeAbstract, DIE *AbsDIE) {
2061+
StringRef Name = DV.getName();
2062+
LLVM_DEBUG(dbgs() << "[DwarfDebug] applying attributes for DIE variable <" << Name << ">\n");
20492063
if (AbsDIE) {
20502064
addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin, AbsDIE);
20512065
} else {
@@ -2063,7 +2077,7 @@ IGC::DIE *CompileUnit::constructVariableDIE(DbgVariable &DV, bool isScopeAbstrac
20632077
if (isScopeAbstract) {
20642078
DV.setDIE(VariableDie);
20652079
LLVM_DEBUG(dbgs() << " done. Variable is scope-abstract\n");
2066-
return VariableDie;
2080+
return;
20672081
}
20682082

20692083
// Add variable address.
@@ -2084,21 +2098,20 @@ IGC::DIE *CompileUnit::constructVariableDIE(DbgVariable &DV, bool isScopeAbstrac
20842098

20852099
DV.setDIE(VariableDie);
20862100
LLVM_DEBUG(dbgs() << " done. Location is taken from .debug_loc\n");
2087-
return VariableDie;
2101+
return;
20882102
}
20892103

20902104
// Check if variable is described by a DBG_VALUE instruction.
20912105
const Instruction *pDbgInst = DV.getDbgInst();
20922106
if (!pDbgInst || !DV.currentLocationIsInlined()) {
20932107
DV.setDIE(VariableDie);
20942108
LLVM_DEBUG(dbgs() << " done. No dbg.inst assotiated\n");
2095-
return VariableDie;
2109+
return;
20962110
}
20972111

20982112
buildLocation(pDbgInst, DV, VariableDie);
20992113

21002114
LLVM_DEBUG(dbgs() << " done. Location is emitted directly in DIE\n");
2101-
return VariableDie;
21022115
}
21032116

21042117
void CompileUnit::buildLocation(const llvm::Instruction *pDbgInst, DbgVariable &DV, IGC::DIE *VariableDie) {

IGC/DebugInfo/DwarfCompileUnit.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,10 @@ class CompileUnit {
357357
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
358358
DIE *constructVariableDIE(DbgVariable &DV, bool isScopeAbstract);
359359

360+
/// Apply attributes for DIE created in constructVariableDIE
361+
void applyVariableAttributes(DbgVariable &DV, DIE *VariableDie, bool isScopeAbstract,
362+
DIE *AbsDIE = nullptr);
363+
360364
/// Create a DIE with the given Tag, add the DIE to its parent, and
361365
/// call insertDIE if MD is not null.
362366
DIE *createAndAddDIE(unsigned Tag, DIE &Parent, llvm::DINode *N = nullptr);

IGC/DebugInfo/DwarfDebug.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,6 @@ DIE *DwarfDebug::createScopeChildrenDIE(CompileUnit *TheCU, LexicalScope *Scope,
675675
DIE *ObjectPointer = NULL;
676676

677677
SmallVector<DbgVariable *, 8> dbgVariables;
678-
679678
// Collect arguments for current function.
680679
if (LScopes.isCurrentFunctionScope(Scope)) {
681680
std::copy(CurrentFnArguments.begin(), CurrentFnArguments.end(), std::back_inserter(dbgVariables));
@@ -687,15 +686,23 @@ DIE *DwarfDebug::createScopeChildrenDIE(CompileUnit *TheCU, LexicalScope *Scope,
687686
std::copy(Variables.begin(), Variables.end(), std::back_inserter(dbgVariables));
688687
}
689688

690-
// Collect all argument/variable children
689+
// Create and collect all argument/variable children
691690
for (DbgVariable *ArgDV : dbgVariables) {
692691
if (!ArgDV)
693692
continue;
694-
if (DIE *Arg = TheCU->constructVariableDIE(*ArgDV, Scope->isAbstractScope())) {
695-
Children.push_back(Arg);
696-
if (ArgDV->isObjectPointer())
697-
ObjectPointer = Arg;
698-
}
693+
DIE *Arg = TheCU->constructVariableDIE(*ArgDV, Scope->isAbstractScope());
694+
Children.push_back(Arg);
695+
if (ArgDV->isObjectPointer())
696+
ObjectPointer = Arg;
697+
}
698+
699+
// Apply attributes to each created DIE. It needs to be done after creating all
700+
// subprogram DIEs, beacuse we might need reference to them in addType() function.
701+
for (DbgVariable *ArgDV : dbgVariables) {
702+
if (!ArgDV)
703+
continue;
704+
if (DIE *VarDIE = TheCU->getDIE(const_cast<DILocalVariable*>(ArgDV->getVariable())))
705+
TheCU->applyVariableAttributes(*ArgDV, VarDIE, Scope->isAbstractScope());
699706
}
700707

701708
// There is no need to emit empty lexical block DIE.
@@ -1158,9 +1165,11 @@ void DwarfDebug::collectDeadVariables() {
11581165
if (!isa<DILocalVariable>(DV))
11591166
continue;
11601167
DbgVariable NewVar(cast<DILocalVariable>(DV));
1161-
if (DIE *VariableDIE = SPCU->constructVariableDIE(NewVar, false)) {
1162-
SPDIE->addChild(VariableDIE);
1168+
DIE *VariableDIE = SPCU->constructVariableDIE(NewVar, false);
1169+
if (SPCU->getDIE(const_cast<DILocalVariable*>(NewVar.getVariable()))) {
1170+
SPCU->applyVariableAttributes(NewVar, VariableDIE, false);
11631171
}
1172+
SPDIE->addChild(VariableDIE);
11641173
}
11651174
}
11661175

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2025 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
9+
; Test checks if DW_AT_string_length is correctly generated for
10+
; vla fortran string array (DIStringType)
11+
12+
; UNSUPPORTED: sys32
13+
14+
; REQUIRES: regkeys, oneapi-readelf, llvm-14-plus, dg2-supported
15+
16+
; RUN: llvm-as -opaque-pointers=0 %s -o %t
17+
; RUN: ocloc compile -llvm_input -file %t -device dg2 -options "-g -cl-opt-disable -igc_opts 'ElfDumpEnable=1, DumpUseShorterName=0, DebugDumpNamePrefix=%t_'"
18+
; RUN: oneapi-readelf --debug-dump %t_OCL_simd8_foo.elf | FileCheck %s
19+
20+
; CHECK: DW_AT_name : vla_string
21+
; CHECK: DW_AT_type : {{.*}}
22+
23+
; CHECK: <{{[0-9]+}}><[[LENGHT:[0-9a-f]+]]>: Abbrev Number: [[#]] (DW_TAG_variable)
24+
; CHECK-NEXT: DW_AT_name : vla_string.len
25+
26+
; CHECK: DW_AT_name : vla_string.type
27+
; CHECK: DW_AT_string_length: <0x[[LENGHT]]>
28+
29+
define spir_func void @subprgm() #0 {
30+
entry:
31+
ret void, !dbg !13
32+
}
33+
34+
define spir_kernel void @foo() #0 {
35+
entry:
36+
call void @subprgm()
37+
ret void
38+
}
39+
40+
attributes #0 = { noinline nounwind optnone }
41+
42+
!llvm.dbg.cu = !{!0}
43+
!llvm.module.flags = !{!1, !2}
44+
45+
!0 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 24.0-1640", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !4)
46+
!1 = !{i32 7, !"Dwarf Version", i32 4}
47+
!2 = !{i32 2, !"Debug Info Version", i32 3}
48+
!3 = !DIFile(filename: "simple-string-type.f90", directory: "/")
49+
!4 = !{}
50+
!5 = distinct !DISubprogram(name: "subprgm", scope: !3, file: !3, line: 256, type: !6, scopeLine: 256, unit: !0, retainedNodes: !8)
51+
!6 = !DISubroutineType(types: !7)
52+
!7 = !{null}
53+
!8 = !{!9, !11}
54+
!9 = !DILocalVariable(name: "vla_string.len", scope: !5, type: !10, flags: DIFlagArtificial)
55+
!10 = !DIBasicType(name: "integer*8", size: 64, encoding: DW_ATE_signed)
56+
!11 = !DILocalVariable(name: "vla_string", arg: 1, scope: !5, file: !3, line: 256, type: !12)
57+
!12 = !DIStringType(name: "vla_string.type", stringLength: !9)
58+
!13 = !DILocation(line: 1, column: 2, scope: !5)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2024 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
9+
; Test whether DW_TAG_string_type is generated in DWARF
10+
11+
; UNSUPPORTED: sys32
12+
13+
; REQUIRES: regkeys, oneapi-readelf, dg2-supported
14+
15+
; RUN: llvm-as -opaque-pointers=0 %s -o %t
16+
; RUN: ocloc compile -llvm_input -file %t -device dg2 -options "-g -cl-opt-disable -igc_opts 'ElfDumpEnable=1, DumpUseShorterName=0, DebugDumpNamePrefix=%t_'"
17+
; RUN: oneapi-readelf --debug-dump %t_OCL_simd32_foo.elf | FileCheck %s
18+
19+
; CHECK: DW_TAG_string_type
20+
; CHECK: DW_AT_name : character(*)
21+
; CHECK: DW_TAG_string_type
22+
; CHECK: DW_AT_name : character(10)
23+
; CHECK: DW_AT_byte_size : 10
24+
; CHECK: DW_TAG_string_type
25+
; CHECK: DW_AT_name : character
26+
; CHECK: DW_AT_encoding : 0 (void)
27+
; CHECK: DW_AT_byte_size : 0
28+
29+
; Function Attrs: noinline nounwind optnone
30+
define spir_kernel void @foo() #0 {
31+
entry:
32+
ret void
33+
}
34+
35+
attributes #0 = { noinline nounwind optnone }
36+
37+
!llvm.dbg.cu = !{!0}
38+
!llvm.module.flags = !{!1, !2}
39+
40+
!0 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 24.0-1640", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !4, imports: !4)
41+
!1 = !{i32 7, !"Dwarf Version", i32 4}
42+
!2 = !{i32 2, !"Debug Info Version", i32 3}
43+
!3 = !DIFile(filename: "simple-string-type.f90", directory: "/")
44+
!4 = !{}
45+
!5 = !{!6, !9, !12, !13}
46+
!6 = !DIStringType(name: "character(*)", stringLength: !7, stringLengthExpression: !DIExpression(), size: 32)
47+
!7 = !DILocalVariable(arg: 2, scope: !8, file: !3, line: 256, type: !11, flags: DIFlagArtificial)
48+
!8 = distinct !DISubprogram(name: "subprgm", scope: !0, file: !3, line: 256, type: !9, isLocal: false, isDefinition: true, scopeLine: 256, isOptimized: false, unit: !0)
49+
!9 = !DISubroutineType(types: !10)
50+
!10 = !{null, !6, !11}
51+
!11 = !DIBasicType(name: "integer*8", size: 64, align: 64, encoding: DW_ATE_signed)
52+
!12 = !DIStringType(name: "character(10)", size: 80, align: 8)
53+
!13 = !DIBasicType(tag: DW_TAG_string_type, name: "character")

0 commit comments

Comments
 (0)