Version: dxcompiler.dll 1.9(5402-0d3ee6b5)(1.9.0.5402) - 1.9.0.5402 (0d3ee6b55-dirty)
lowered_global.zip
Static globals are lowered to SSA values and mirrored into a synthetic
DILocalVariable named global.<name>. That variable is scoped to a function
subprogram and carries no reference to the declaring namespace or class, and no
link back to the DIGlobalVariable that does have the correct scope.
Repro 1: namespace
dxc -T cs_6_0 -Zi -Qembed_debug -Od -Fc namespace_static.ll namespace_static.hlsl
namespace A { static int MyNum = 67; } // line 11
namespace B { static int MyNum = 68; } // line 15
[numthreads(1, 1, 1)]
void main()
{
A::MyNum = input[0];
B::MyNum = input[1];
output[0] = A::MyNum + B::MyNum;
}
Actual
!42 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "global.MyNum", arg: 0, scope: !4, file: !1, line: 15, type: !12)
!45 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "global.MyNum", arg: 0, scope: !4, file: !1, line: 11, type: !12)
!4 is the main subprogram for both, so A::MyNum and B::MyNum are
indistinguishable apart from line:.
The namespace is present elsewhere in the module, just not reachable from the
local:
!14 = !DIGlobalVariable(name: "MyNum", linkageName: "\01?MyNum@A@@3HA", scope: !15, file: !1, line: 11, ...)
!15 = !DINamespace(name: "A", scope: null, file: !1, line: 10)
!16 = !DIGlobalVariable(name: "MyNum", linkageName: "\01?MyNum@B@@3HA", scope: !17, file: !1, line: 15, ...)
!17 = !DINamespace(name: "B", scope: null, file: !1, line: 14)
Repro 2: class static member
dxc -T cs_6_0 -Zi -Qembed_debug -Od -Fc class_static_member.ll class_static_member.hlsl
class Counter
{
static int count;
int localValue;
void Initialize(int value) { localValue = value; count += value; }
};
int Counter::count = 0; // line 23
Actual
One global.count is emitted per function that touches the static, each scoped
to that function's subprogram:
!48 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "global.count", arg: 0, scope: !7, file: !1, line: 23, type: !11)
!51 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "global.count", arg: 0, scope: !4, file: !1, line: 23, type: !11)
!4 = !DISubprogram(name: "main", ...)
!7 = !DISubprogram(name: "Initialize", linkageName: "\01?Initialize@Counter@@QAAXH@Z", scope: !8, ...)
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !48, metadata !49), !dbg !50 ; var:"global.count" !DIExpression() func:"Initialize"
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !51, metadata !49), !dbg !52 ; var:"global.count" !DIExpression() func:"main"
call void @llvm.dbg.value(metadata i32 %6, i64 0, metadata !48, metadata !49), !dbg !50 ; var:"global.count" !DIExpression() func:"Initialize"
call void @llvm.dbg.value(metadata i32 %6, i64 0, metadata !51, metadata !49), !dbg !52 ; var:"global.count" !DIExpression() func:"main"
Expected
There should be a way to link a global lowered to local back to the original global, something like:
!dx.dbg.local_globals = {!100, !101}
!100 = !{ !48, !23 }
!101 = !{ !51, !23 }
!8 = !DICompositeType(tag: DW_TAG_class_type, name: "Counter", file: !1, line: 11, size: 32, align: 32, elements: !9)
!10 = !DIDerivedType(tag: DW_TAG_member, name: "count", scope: !8, file: !1, line: 13, baseType: !11, flags: DIFlagPublic | DIFlagStaticMember)
!23 = !DIGlobalVariable(name: "count", linkageName: "\01?count@Counter@@2HA", scope: !0, file: !1, line: 23, type: !11, isLocal: true, isDefinition: true, declaration: !10)
!48 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "global.count", arg: 0, scope: !7, file: !1, line: 23, type: !11)
!51 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "global.count", arg: 0, scope: !4, file: !1, line: 23, type: !11)
So the backend can reconstruct the correct scope information if appropriate.
Version:
dxcompiler.dll 1.9(5402-0d3ee6b5)(1.9.0.5402) - 1.9.0.5402 (0d3ee6b55-dirty)lowered_global.zip
Static globals are lowered to SSA values and mirrored into a synthetic
DILocalVariablenamedglobal.<name>. That variable is scoped to a functionsubprogram and carries no reference to the declaring namespace or class, and no
link back to the
DIGlobalVariablethat does have the correct scope.Repro 1: namespace
Actual
!4is themainsubprogram for both, soA::MyNumandB::MyNumareindistinguishable apart from
line:.The namespace is present elsewhere in the module, just not reachable from the
local:
Repro 2: class static member
Actual
One
global.countis emitted per function that touches the static, each scopedto that function's subprogram:
Expected
There should be a way to link a global lowered to local back to the original global, something like:
So the backend can reconstruct the correct scope information if appropriate.