From 2d38cb684b30fb165024e41a56be8a16ecef4e46 Mon Sep 17 00:00:00 2001 From: Steve Urquhart Date: Thu, 11 Sep 2025 13:31:32 -0400 Subject: [PATCH] [SPIRV] Emit DebugLexicalScope for forloop controls (#8514) --- tools/clang/lib/SPIRV/SpirvEmitter.cpp | 20 +++++++++++++++++++ .../rich.debug.debuglexicalblock.hlsl | 11 +++++----- .../CodeGenSPIRV/rich.debug.debugscope.hlsl | 17 +++++++++------- .../shader.debug.debuglexicalblock.hlsl | 11 +++++----- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.cpp b/tools/clang/lib/SPIRV/SpirvEmitter.cpp index 288b926f24..7b0abd938a 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.cpp +++ b/tools/clang/lib/SPIRV/SpirvEmitter.cpp @@ -2719,6 +2719,20 @@ void SpirvEmitter::doForStmt(const ForStmt *forStmt, attrs.empty() ? spv::LoopControlMask::MaskNone : translateLoopAttribute(forStmt, *attrs.front()); + RichDebugInfo *info = nullptr; + if (spirvOptions.debugInfoRich) { + const auto &sm = astContext.getSourceManager(); + auto loc = forStmt->getForLoc(); + const uint32_t line = sm.getPresumedLineNumber(loc); + const uint32_t column = sm.getPresumedColumnNumber(loc); + info = getOrCreateRichDebugInfo(loc); + auto *debugLexicalBlock = spvBuilder.createDebugLexicalBlock( + info->source, line, column, info->scopeStack.back()); + + // Add this lexical block to the stack of lexical scopes. + spvContext.pushDebugLexicalScope(info, debugLexicalBlock); + } + const Stmt *initStmt = forStmt->getInit(); const Stmt *body = forStmt->getBody(); const Expr *check = forStmt->getCond(); @@ -2842,6 +2856,12 @@ void SpirvEmitter::doForStmt(const ForStmt *forStmt, // Done with the current scope's continue block and merge block. continueStack.pop(); breakStack.pop(); + + if (spirvOptions.debugInfoRich) { + // We are done with processing this compound statement. Remove its + // lexical block from the stack of lexical scopes. + spvContext.popDebugLexicalScope(info); + } } void SpirvEmitter::doIfStmt(const IfStmt *ifStmt, diff --git a/tools/clang/test/CodeGenSPIRV/rich.debug.debuglexicalblock.hlsl b/tools/clang/test/CodeGenSPIRV/rich.debug.debuglexicalblock.hlsl index 647b584852..5696e8386d 100644 --- a/tools/clang/test/CodeGenSPIRV/rich.debug.debuglexicalblock.hlsl +++ b/tools/clang/test/CodeGenSPIRV/rich.debug.debuglexicalblock.hlsl @@ -3,11 +3,12 @@ // CHECK: [[debugSet:%[0-9]+]] = OpExtInstImport "OpenCL.DebugInfo.100" // CHECK: [[debugSource:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugSource // CHECK: [[main:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugFunction -// CHECK: [[mainFnLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] 13 1 [[main]] -// CHECK: [[whileLoopLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] 21 3 [[mainFnLexBlock]] -// CHECK: [[ifStmtLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] 26 20 [[whileLoopLexBlock]] -// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] 28 7 [[ifStmtLexBlock]] -// CHECK: [[forLoopLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] 15 12 [[mainFnLexBlock]] +// CHECK: [[mainFnLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] 14 1 [[main]] +// CHECK: [[whileLoopLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] 22 3 [[mainFnLexBlock]] +// CHECK: [[ifStmtLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] 27 20 [[whileLoopLexBlock]] +// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] 29 7 [[ifStmtLexBlock]] +// CHECK: [[forLoopParensLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] 16 3 [[mainFnLexBlock]] +// CHECK: [[forLoopLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] 16 12 [[forLoopParensLexBlock]] float4 main(float4 color : COLOR) : SV_TARGET { diff --git a/tools/clang/test/CodeGenSPIRV/rich.debug.debugscope.hlsl b/tools/clang/test/CodeGenSPIRV/rich.debug.debugscope.hlsl index f844668a68..82448ebcfc 100644 --- a/tools/clang/test/CodeGenSPIRV/rich.debug.debugscope.hlsl +++ b/tools/clang/test/CodeGenSPIRV/rich.debug.debugscope.hlsl @@ -3,11 +3,12 @@ // CHECK: [[set:%[0-9]+]] = OpExtInstImport "OpenCL.DebugInfo.100" // CHECK: [[compUnit:%[0-9]+]] = OpExtInst %void [[set]] DebugCompilationUnit // CHECK: [[srcMain:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction -// CHECK: [[srcMainFnLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 17 1 [[srcMain]] -// CHECK: [[whileLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 37 3 [[srcMainFnLexBlock]] -// CHECK: [[ifStmtLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 44 20 [[whileLoopLexBlock]] -// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 49 7 [[ifStmtLexBlock]] -// CHECK: [[forLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 22 12 [[srcMainFnLexBlock]] +// CHECK: [[srcMainFnLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 18 1 [[srcMain]] +// CHECK: [[whileLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 40 3 [[srcMainFnLexBlock]] +// CHECK: [[ifStmtLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 47 20 [[whileLoopLexBlock]] +// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 52 7 [[ifStmtLexBlock]] +// CHECK: [[forLoopParensLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 23 3 [[srcMainFnLexBlock]] +// CHECK: [[forLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 23 12 [[forLoopParensLexBlock]] // CHECK: [[main:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction float4 main(float4 color : COLOR) : SV_TARGET @@ -20,16 +21,18 @@ float4 main(float4 color : COLOR) : SV_TARGET float4 c = 0.xxxx; for (;;) { +// CHECK: %for_check = OpLabel +// CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[forLoopParensLexBlock]] // CHECK: %for_body = OpLabel // CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[forLoopLexBlock]] float4 a = 0.xxxx; float4 b = 1.xxxx; c = c + a + b; // CHECK: %for_continue = OpLabel -// CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[srcMainFnLexBlock]] +// CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[forLoopParensLexBlock]] } // CHECK: %for_merge = OpLabel -// CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[srcMainFnLexBlock]] +// CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[forLoopParensLexBlock]] // CHECK: %while_check = OpLabel // CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[srcMainFnLexBlock]] diff --git a/tools/clang/test/CodeGenSPIRV/shader.debug.debuglexicalblock.hlsl b/tools/clang/test/CodeGenSPIRV/shader.debug.debuglexicalblock.hlsl index 429aa061d4..f2a8d3a571 100644 --- a/tools/clang/test/CodeGenSPIRV/shader.debug.debuglexicalblock.hlsl +++ b/tools/clang/test/CodeGenSPIRV/shader.debug.debuglexicalblock.hlsl @@ -3,11 +3,12 @@ // CHECK: [[debugSet:%[0-9]+]] = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" // CHECK: [[debugSource:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugSource // CHECK: [[main:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugFunction -// CHECK: [[mainFnLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] %uint_13 %uint_1 [[main]] -// CHECK: [[whileLoopLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] %uint_21 %uint_3 [[mainFnLexBlock]] -// CHECK: [[ifStmtLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] %uint_26 %uint_20 [[whileLoopLexBlock]] -// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] %uint_28 %uint_7 [[ifStmtLexBlock]] -// CHECK: [[forLoopLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] %uint_15 %uint_12 [[mainFnLexBlock]] +// CHECK: [[mainFnLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] %uint_14 %uint_1 [[main]] +// CHECK: [[whileLoopLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] %uint_22 %uint_3 [[mainFnLexBlock]] +// CHECK: [[ifStmtLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] %uint_27 %uint_20 [[whileLoopLexBlock]] +// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] %uint_29 %uint_7 [[ifStmtLexBlock]] +// CHECK: [[forLoopParensLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] %uint_16 %uint_3 [[mainFnLexBlock]] +// CHECK: [[forLoopLexBlock:%[0-9]+]] = OpExtInst %void [[debugSet]] DebugLexicalBlock [[debugSource]] %uint_16 %uint_12 [[forLoopParensLexBlock]] float4 main(float4 color : COLOR) : SV_TARGET {