Skip to content

Commit

Permalink
[SPIRV] Emit DebugFunction and Definition for both wrapper and real f…
Browse files Browse the repository at this point in the history
…unctions
  • Loading branch information
SteveUrquhart committed Oct 17, 2024
1 parent dfa1c81 commit 565af65
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 25 deletions.
76 changes: 52 additions & 24 deletions tools/clang/lib/SPIRV/SpirvEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1453,25 +1453,7 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
SpirvDebugInstruction *outer_scope = spvContext.getCurrentLexicalScope();
const auto &sm = astContext.getSourceManager();
if (spirvOptions.debugInfoRich && decl->hasBody()) {
const uint32_t line = sm.getPresumedLineNumber(loc);
const uint32_t column = sm.getPresumedColumnNumber(loc);
info = getOrCreateRichDebugInfo(loc);

auto *source = info->source;
// Note that info->scopeStack.back() is a lexical scope of the function
// caller.
auto *parentScope = info->compilationUnit;
// TODO: figure out the proper flag based on the function decl.
// using FlagIsPublic for now.
uint32_t flags = 3u;
// The line number in the source program at which the function scope begins.
auto scopeLine = sm.getPresumedLineNumber(decl->getBody()->getLocStart());
debugFunction = spvBuilder.createDebugFunction(decl, debugFuncName, source,
line, column, parentScope,
"", flags, scopeLine, func);
func->setDebugScope(new (spvContext) SpirvDebugScope(debugFunction));

spvContext.pushDebugLexicalScope(info, debugFunction);
debugFunction = emitDebugFunction(decl, func, &info, funcName);
}

bool isEntry = false;
Expand All @@ -1481,14 +1463,18 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
if (entryInfo->isEntryFunction) {
isEntry = true;
funcName = "src." + funcName;
SpirvDebugFunction *wrapperDebugFunction = nullptr;
if (spirvOptions.debugInfoRich && decl->hasBody()) {
wrapperDebugFunction = emitDebugFunction(decl, func, &info, funcName);
}
// Create wrapper for the entry function
if (!emitEntryFunctionWrapper(decl, func))
if (!emitEntryFunctionWrapper(decl, wrapperDebugFunction, func))
return;
// Generate DebugEntryPoint if function definition
if (spirvOptions.debugInfoVulkan && debugFunction) {
if (spirvOptions.debugInfoVulkan && wrapperDebugFunction) {
auto *cu = dyn_cast<SpirvDebugCompilationUnit>(outer_scope);
assert(cu && "expected DebugCompilationUnit");
spvBuilder.createDebugEntryPoint(debugFunction, cu,
spvBuilder.createDebugEntryPoint(wrapperDebugFunction, cu,
clang::getGitCommitHash(),
spirvOptions.clOptions);
}
Expand Down Expand Up @@ -13197,11 +13183,17 @@ bool SpirvEmitter::processTessellationShaderAttributes(
}

bool SpirvEmitter::emitEntryFunctionWrapperForRayTracing(
const FunctionDecl *decl, SpirvFunction *entryFuncInstr) {
const FunctionDecl *decl, SpirvDebugFunction *debugFunction,
SpirvFunction *entryFuncInstr) {
// The entry basic block.
auto *entryLabel = spvBuilder.createBasicBlock();
spvBuilder.setInsertPoint(entryLabel);

// Add DebugFunctionDefinition if we are emitting
// NonSemantic.Shader.DebugInfo.100 debug info.
if (spirvOptions.debugInfoVulkan && debugFunction)
spvBuilder.createDebugFunctionDef(debugFunction, entryFunction);

// Initialize all global variables at the beginning of the wrapper
for (const VarDecl *varDecl : toInitGloalVars) {
const auto varInfo =
Expand Down Expand Up @@ -13464,7 +13456,37 @@ bool SpirvEmitter::processMeshOrAmplificationShaderAttributes(
return true;
}

SpirvDebugFunction *SpirvEmitter::emitDebugFunction(const FunctionDecl *decl,
SpirvFunction *func,
RichDebugInfo **info,
std::string name) {
auto loc = decl->getLocStart();
auto range = decl->getSourceRange();
const auto &sm = astContext.getSourceManager();
const uint32_t line = sm.getPresumedLineNumber(loc);
const uint32_t column = sm.getPresumedColumnNumber(loc);
*info = getOrCreateRichDebugInfo(loc);

SpirvDebugSource *source = (*info)->source;
// Note that info->scopeStack.back() is a lexical scope of the function
// caller.
SpirvDebugInstruction *parentScope = (*info)->compilationUnit;
// TODO: figure out the proper flag based on the function decl.
// using FlagIsPublic for now.
uint32_t flags = 3u;
// The line number in the source program at which the function scope begins.
auto scopeLine = sm.getPresumedLineNumber(decl->getBody()->getLocStart());
SpirvDebugFunction *debugFunction =
spvBuilder.createDebugFunction(decl, name, source, line, column,
parentScope, "", flags, scopeLine, func);
func->setDebugScope(new (spvContext) SpirvDebugScope(debugFunction));

spvContext.pushDebugLexicalScope(*info, debugFunction);
return debugFunction;
}

bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
SpirvDebugFunction *debugFunction,
SpirvFunction *entryFuncInstr) {
// HS specific attributes
uint32_t numOutputControlPoints = 0;
Expand Down Expand Up @@ -13500,7 +13522,8 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
entryInfo->entryFunction = entryFunction;

if (spvContext.isRay()) {
return emitEntryFunctionWrapperForRayTracing(decl, entryFuncInstr);
return emitEntryFunctionWrapperForRayTracing(decl, debugFunction,
entryFuncInstr);
}
// Handle attributes specific to each shader stage
if (spvContext.isPS()) {
Expand Down Expand Up @@ -13581,6 +13604,11 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
// after the basic block is created and insert point is set.
processInlineSpirvAttributes(decl);

// Add DebugFunctionDefinition if we are emitting
// NonSemantic.Shader.DebugInfo.100 debug info.
if (spirvOptions.debugInfoVulkan && debugFunction)
spvBuilder.createDebugFunctionDef(debugFunction, entryFunction);

// Initialize all global variables at the beginning of the wrapper
for (const VarDecl *varDecl : toInitGloalVars) {
// SPIR-V does not have string variables
Expand Down
8 changes: 8 additions & 0 deletions tools/clang/lib/SPIRV/SpirvEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,12 @@ class SpirvEmitter : public ASTConsumer {
processMeshOrAmplificationShaderAttributes(const FunctionDecl *decl,
uint32_t *outVerticesArraySize);

/// \brief Emits a SpirvDebugFunction to match given SpirvFunction, and
/// returns a pointer to it.
SpirvDebugFunction *emitDebugFunction(const FunctionDecl *decl,
SpirvFunction *func,
RichDebugInfo **info, std::string name);

/// \brief Emits a wrapper function for the entry function and returns true
/// on success.
///
Expand All @@ -854,6 +860,7 @@ class SpirvEmitter : public ASTConsumer {
/// The wrapper function is also responsible for initializing global static
/// variables for some cases.
bool emitEntryFunctionWrapper(const FunctionDecl *entryFunction,
SpirvDebugFunction *debugFunction,
SpirvFunction *entryFuncId);

/// \brief Emits a wrapper function for the entry functions for raytracing
Expand All @@ -864,6 +871,7 @@ class SpirvEmitter : public ASTConsumer {
/// The wrapper function is also responsible for initializing global static
/// variables for some cases.
bool emitEntryFunctionWrapperForRayTracing(const FunctionDecl *entryFunction,
SpirvDebugFunction *debugFunction,
SpirvFunction *entryFuncId);

/// \brief Performs the following operations for the Hull shader:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// CHECK: [[emptyStr:%[0-9]+]] = OpString ""
// CHECK: [[y:%[0-9]+]] = OpString "y"
// CHECK: [[x:%[0-9]+]] = OpString "x"
// CHECK: [[mainName:%[0-9]+]] = OpString "main"
// CHECK: [[mainName:%[0-9]+]] = OpString "src.main"
// CHECK: [[color:%[0-9]+]] = OpString "color"

// CHECK: [[int:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Signed
Expand Down

0 comments on commit 565af65

Please sign in to comment.