[SPIRV] Emit DebugFunction/Definition for both wrapper and real functions (#6966)

https://github.com/microsoft/DirectXShaderCompiler/pull/6758
unfortunately caused a regression for shaders compiled without -fcgl.
This PR extends the original fix and corrects the regression. We now
emit DebugFunction and DebugFunctionDefinition pairs for both the
wrapper and the main functions, and a DebugEntrypoint that points at the
wrapper function. This survives inlining.
This commit is contained in:
Steve Urquhart 2024-11-18 20:01:12 -05:00 коммит произвёл GitHub
Родитель 72b353a345
Коммит 891392e87e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
8 изменённых файлов: 160 добавлений и 90 удалений

Просмотреть файл

@ -1442,37 +1442,16 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
// This will allow the entry-point name to be something like
// myNamespace::myEntrypointFunc.
std::string funcName = getFnName(decl);
std::string debugFuncName = funcName;
std::string srcFuncName = "src." + funcName;
SpirvFunction *func = declIdMapper.getOrRegisterFn(decl);
SpirvFunction *srcFunc = nullptr;
auto loc = decl->getLocStart();
auto range = decl->getSourceRange();
RichDebugInfo *info = nullptr;
SpirvDebugFunction *debugFunction = nullptr;
SpirvDebugFunction *srcDebugFunction = nullptr;
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);
}
bool isEntry = false;
const auto iter = functionInfoMap.find(decl);
@ -1480,10 +1459,17 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
const auto &entryInfo = iter->second;
if (entryInfo->isEntryFunction) {
isEntry = true;
funcName = "src." + funcName;
// Create wrapper for the entry function
if (!emitEntryFunctionWrapper(decl, func))
srcFunc = func;
func = emitEntryFunctionWrapper(decl, &info, &debugFunction, srcFunc);
if (func == nullptr)
return;
if (spirvOptions.debugInfoRich && decl->hasBody()) {
// use the HLSL name the debug user will expect to see
srcDebugFunction = emitDebugFunction(decl, srcFunc, &info, funcName);
}
// Generate DebugEntryPoint if function definition
if (spirvOptions.debugInfoVulkan && debugFunction) {
auto *cu = dyn_cast<SpirvDebugCompilationUnit>(outer_scope);
@ -1492,15 +1478,30 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
clang::getGitCommitHash(),
spirvOptions.clOptions);
}
} else {
if (spirvOptions.debugInfoRich && decl->hasBody()) {
debugFunction = emitDebugFunction(decl, func, &info, funcName);
}
}
}
if (spirvOptions.debugInfoRich) {
spvContext.pushDebugLexicalScope(info, debugFunction);
}
const QualType retType =
declIdMapper.getTypeAndCreateCounterForPotentialAliasVar(decl);
spvBuilder.beginFunction(retType, decl->getLocStart(), funcName,
decl->hasAttr<HLSLPreciseAttr>(),
decl->hasAttr<NoInlineAttr>(), func);
if (srcFunc) {
spvBuilder.beginFunction(retType, decl->getLocStart(), srcFuncName,
decl->hasAttr<HLSLPreciseAttr>(),
decl->hasAttr<NoInlineAttr>(), srcFunc);
} else {
spvBuilder.beginFunction(retType, decl->getLocStart(), funcName,
decl->hasAttr<HLSLPreciseAttr>(),
decl->hasAttr<NoInlineAttr>(), func);
}
bool isNonStaticMemberFn = false;
if (const auto *memberFn = dyn_cast<CXXMethodDecl>(decl)) {
@ -1551,7 +1552,9 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
// Add DebugFunctionDefinition if we are emitting
// NonSemantic.Shader.DebugInfo.100 debug info
if (spirvOptions.debugInfoVulkan && debugFunction)
if (spirvOptions.debugInfoVulkan && srcDebugFunction)
spvBuilder.createDebugFunctionDef(srcDebugFunction, srcFunc);
else if (spirvOptions.debugInfoVulkan && debugFunction)
spvBuilder.createDebugFunctionDef(debugFunction, func);
// Process all statments in the body.
@ -13331,11 +13334,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 =
@ -13598,8 +13607,36 @@ bool SpirvEmitter::processMeshOrAmplificationShaderAttributes(
return true;
}
bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
SpirvFunction *entryFuncInstr) {
SpirvDebugFunction *SpirvEmitter::emitDebugFunction(const FunctionDecl *decl,
SpirvFunction *func,
RichDebugInfo **info,
std::string name) {
auto loc = decl->getLocStart();
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));
return debugFunction;
}
SpirvFunction *SpirvEmitter::emitEntryFunctionWrapper(
const FunctionDecl *decl, RichDebugInfo **info,
SpirvDebugFunction **debugFunction, SpirvFunction *entryFuncInstr) {
// HS specific attributes
uint32_t numOutputControlPoints = 0;
SpirvInstruction *outputControlPointIdVal =
@ -13620,6 +13657,10 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
entryFunction = spvBuilder.beginFunction(
astContext.VoidTy, decl->getLocStart(), decl->getName());
if (spirvOptions.debugInfoRich && decl->hasBody()) {
*debugFunction = emitDebugFunction(decl, entryFunction, info, "wrapper");
}
// Specify that entryFunction is an entry function wrapper.
entryFunction->setEntryFunctionWrapper();
@ -13634,7 +13675,10 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
entryInfo->entryFunction = entryFunction;
if (spvContext.isRay()) {
return emitEntryFunctionWrapperForRayTracing(decl, entryFuncInstr);
return emitEntryFunctionWrapperForRayTracing(decl, *debugFunction,
entryFuncInstr)
? entryFunction
: nullptr;
}
// Handle attributes specific to each shader stage
if (spvContext.isPS()) {
@ -13643,7 +13687,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
processComputeShaderAttributes(decl);
} else if (spvContext.isHS()) {
if (!processTessellationShaderAttributes(decl, &numOutputControlPoints))
return false;
return nullptr;
// The input array size for HS is specified in the InputPatch parameter.
for (const auto *param : decl->params())
@ -13655,7 +13699,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
outputArraySize = numOutputControlPoints;
} else if (spvContext.isDS()) {
if (!processTessellationShaderAttributes(decl, &numOutputControlPoints))
return false;
return nullptr;
// The input array size for HS is specified in the OutputPatch parameter.
for (const auto *param : decl->params())
@ -13666,11 +13710,11 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
// The per-vertex output of DS is not an array.
} else if (spvContext.isGS()) {
if (!processGeometryShaderAttributes(decl, &inputArraySize))
return false;
return nullptr;
// The per-vertex output of GS is not an array.
} else if (spvContext.isMS() || spvContext.isAS()) {
if (!processMeshOrAmplificationShaderAttributes(decl, &outputArraySize))
return false;
return nullptr;
}
// Go through all parameters and record the declaration of SV_ClipDistance
@ -13686,14 +13730,14 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
for (const auto *param : decl->params()) {
if (canActAsInParmVar(param))
if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(param, true))
return false;
return nullptr;
if (canActAsOutParmVar(param))
if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(param, false))
return false;
return nullptr;
}
// Also consider the SV_ClipDistance/SV_CullDistance in the return type
if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(decl, false))
return false;
return nullptr;
// Calculate the total size of the ClipDistance/CullDistance array and the
// offset of SV_ClipDistance/SV_CullDistance variables within the array.
@ -13715,6 +13759,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
@ -13766,7 +13815,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
SpirvInstruction *loadedValue = nullptr;
if (!declIdMapper.createStageInputVar(param, &loadedValue, false))
return false;
return nullptr;
// Only initialize the temporary variable if the parameter is indeed used,
// or if it is an inout parameter.
@ -13805,15 +13854,15 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
// Create stage output variables out of the return type.
if (!declIdMapper.createStageOutputVar(decl, numOutputControlPoints,
outputControlPointIdVal, retVal))
return false;
return nullptr;
if (!processHSEntryPointOutputAndPCF(
decl, retType, retVal, numOutputControlPoints,
outputControlPointIdVal, primitiveIdVar, viewIdVar,
hullMainInputPatchParam))
return false;
return nullptr;
} else {
if (!declIdMapper.createStageOutputVar(decl, retVal, /*forPCF*/ false))
return false;
return nullptr;
}
// Create and write stage output variables for parameters marked as
@ -13836,7 +13885,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
param->getLocStart());
if (!declIdMapper.createStageOutputVar(param, loadedParam, false))
return false;
return nullptr;
}
}
@ -13851,7 +13900,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
if (spvContext.isHS())
doDecl(patchConstFunc);
return true;
return entryFunction;
}
bool SpirvEmitter::processHSEntryPointOutputAndPCF(

Просмотреть файл

@ -848,8 +848,14 @@ private:
processMeshOrAmplificationShaderAttributes(const FunctionDecl *decl,
uint32_t *outVerticesArraySize);
/// \brief Emits a wrapper function for the entry function and returns true
/// on success.
/// \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 a
/// pointer to the wrapper SpirvFunction on success.
///
/// The wrapper function loads the values of all stage input variables and
/// creates composites as expected by the source code entry function. It then
@ -859,8 +865,10 @@ private:
///
/// The wrapper function is also responsible for initializing global static
/// variables for some cases.
bool emitEntryFunctionWrapper(const FunctionDecl *entryFunction,
SpirvFunction *entryFuncId);
SpirvFunction *emitEntryFunctionWrapper(const FunctionDecl *entryFunction,
RichDebugInfo **info,
SpirvDebugFunction **debugFunction,
SpirvFunction *entryFuncId);
/// \brief Emits a wrapper function for the entry functions for raytracing
/// stages and returns true on success.
@ -870,6 +878,7 @@ private:
/// 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:

Просмотреть файл

@ -3,15 +3,17 @@
// CHECK: [[set:%[0-9]+]] = OpExtInstImport "OpenCL.DebugInfo.100"
// CHECK: [[compUnit:%[0-9]+]] = OpExtInst %void [[set]] DebugCompilationUnit
// CHECK: [[main:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction
// CHECK: [[mainFnLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 15 1 [[main]]
// CHECK: [[whileLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 35 3 [[mainFnLexBlock]]
// CHECK: [[ifStmtLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 42 20 [[whileLoopLexBlock]]
// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 47 7 [[ifStmtLexBlock]]
// CHECK: [[forLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 20 12 [[mainFnLexBlock]]
// CHECK: [[mainFnLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 17 1 [[main]]
// CHECK: [[whileLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 37 3 [[mainFnLexBlock]]
// 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 [[mainFnLexBlock]]
// CHECK: [[srcMain:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction
float4 main(float4 color : COLOR) : SV_TARGET
// CHECK: %main = OpFunction
// CHECK: %src_main = OpFunction
// CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[main]]
// CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[srcMain]]
{
// CHECK: %bb_entry = OpLabel
// CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[mainFnLexBlock]]

Просмотреть файл

@ -7,18 +7,20 @@
// 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 "wrapper"
// CHECK: [[color:%[0-9]+]] = OpString "color"
// CHECK: [[srcMainName:%[0-9]+]] = OpString "main"
// CHECK: [[int:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Signed
// CHECK: [[float:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Float
// CHECK: [[source:%[0-9]+]] = OpExtInst %void [[set]] DebugSource
// CHECK: [[foo:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[fooName]] {{%[0-9]+}} [[source]] 23 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 24 %foo
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[y]] [[float]] [[source]] 23 23 [[foo]] FlagIsLocal 2
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[x]] [[int]] [[source]] 23 14 [[foo]] FlagIsLocal 1
// CHECK: [[foo:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[fooName]] {{%[0-9]+}} [[source]] 25 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 26 %foo
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[y]] [[float]] [[source]] 25 23 [[foo]] FlagIsLocal 2
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[x]] [[int]] [[source]] 25 14 [[foo]] FlagIsLocal 1
// CHECK: [[srcMain:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[mainName]] {{%[0-9]+}} [[source]] 30 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 31 %main
// CHECK: [[float4:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeVector [[float]] 4
// CHECK: [[main:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[mainName]] {{%[0-9]+}} [[source]] 28 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 29 %src_main
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[color]] [[float4]] [[source]] 28 20 [[main]] FlagIsLocal 1
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[color]] [[float4]] [[source]] 30 20 [[srcMain]] FlagIsLocal 1
// CHECK: [[main:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[srcMainName]] {{%[0-9]+}} [[source]] 30 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 31 %src_main
void foo(int x, float y)
{

Просмотреть файл

@ -4,15 +4,14 @@
// CHECK: [[varNameCond:%[0-9]+]] = OpString "cond"
// CHECK: [[varNameC:%[0-9]+]] = OpString "c"
// CHECK: [[floatType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Float
// CHECK: [[float4Type:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeVector [[floatType]] 4
// CHECK: [[source:%[0-9]+]] = OpExtInst %void [[set]] DebugSource
// CHECK: [[compileUnit:%[0-9]+]] = OpExtInst %void [[set]] DebugCompilationUnit 1 4 [[source]] HLSL
// CHECK: [[floatType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Float
// CHECK: [[float4Type:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeVector [[floatType]] 4
// CHECK: [[boolType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Boolean
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugGlobalVariable [[varNameCond]] [[boolType]] [[source]] 18 13 [[compileUnit]] [[varNameCond]] %cond FlagIsDefinition
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugGlobalVariable [[varNameC]] [[float4Type]] [[source]] 17 15 [[compileUnit]] [[varNameC]] %c FlagIsDefinition
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugGlobalVariable [[varNameCond]] [[boolType]] [[source]] 17 13 [[compileUnit]] [[varNameCond]] %cond FlagIsDefinition
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugGlobalVariable [[varNameC]] [[float4Type]] [[source]] 16 15 [[compileUnit]] [[varNameC]] %c FlagIsDefinition
static float4 c;
static bool cond;

Просмотреть файл

@ -7,24 +7,26 @@
// CHECK: [[varNameC:%[0-9]+]] = OpString "c"
// CHECK: [[uintType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Unsigned
// CHECK: [[floatType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Float
// CHECK: [[float4Type:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeVector [[floatType]] 4
// CHECK: [[source:%[0-9]+]] = OpExtInst %void [[set]] DebugSource
// CHECK: [[source:%[0-9]+]] = OpExtInst %void [[set]] DebugSource
// CHECK: [[compileUnit:%[0-9]+]] = OpExtInst %void [[set]] DebugCompilationUnit 1 4 [[source]] HLSL
// CHECK: [[main:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction {{%[0-9]+}} {{%[0-9]+}} [[source]] 29 1 [[compileUnit]] {{%[0-9]+}} FlagIsProtected|FlagIsPrivate 30 %src_main
// CHECK: [[main:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction
// CHECK: [[mainFnLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock [[source]] 30 1 [[main]]
// CHECK: [[ifLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock [[source]] 35 13 [[mainFnLexBlock]]
// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock [[source]] 38 5 [[ifLexBlock]]
// CHECK: [[mainFnLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock [[source]] 32 1 [[main]]
// CHECK: [[ifLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock [[source]] 37 13 [[mainFnLexBlock]]
// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock [[source]] 40 5 [[ifLexBlock]]
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameB]] [[uintType]] [[source]] 39 12 [[tempLexBlock]] FlagIsLocal
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameB]] [[uintType]] [[source]] 41 12 [[tempLexBlock]] FlagIsLocal
// CHECK: [[intType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Signed
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameA]] [[intType]] [[source]] 36 9 [[ifLexBlock]] FlagIsLocal
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameA]] [[intType]] [[source]] 38 9 [[ifLexBlock]] FlagIsLocal
// CHECK: [[boolType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Boolean
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameCond]] [[boolType]] [[source]] 32 8 [[mainFnLexBlock]] FlagIsLocal
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameC]] [[float4Type]] [[source]] 31 10 [[mainFnLexBlock]] FlagIsLocal
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameCond]] [[boolType]] [[source]] 34 8 [[mainFnLexBlock]] FlagIsLocal
// CHECK: [[floatType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Float
// CHECK: [[float4Type:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeVector [[floatType]] 4
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameC]] [[float4Type]] [[source]] 33 10 [[mainFnLexBlock]] FlagIsLocal
float4 main(float4 color : COLOR) : SV_TARGET
{

Просмотреть файл

@ -2,11 +2,11 @@
// CHECK: [[set:%[0-9]+]] = OpExtInstImport "OpenCL.DebugInfo.100"
// CHECK: [[float64Name:%[0-9]+]] = OpString "float64_t"
// CHECK: [[floatName:%[0-9]+]] = OpString "float"
// CHECK: [[float16Name:%[0-9]+]] = OpString "float16_t"
// CHECK: [[floatName:%[0-9]+]] = OpString "float"
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugTypeBasic [[float64Name]] %uint_64 Float
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugTypeBasic [[floatName]] %uint_32 Float
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugTypeBasic [[float16Name]] %uint_16 Float
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugTypeBasic [[floatName]] %uint_32 Float
float4 main(float4 color : COLOR) : SV_TARGET {
float a = 0;

Просмотреть файл

@ -5,8 +5,9 @@
// CHECK: [[set:%[0-9]+]] = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
// CHECK: [[fooName:%[0-9]+]] = OpString "foo"
// CHECK: [[emptyStr:%[0-9]+]] = OpString ""
// CHECK: [[mainName:%[0-9]+]] = OpString "main"
// CHECK: [[clOpts:%[0-9]+]] = OpString " -E main -T ps_6_0 -spirv -fcgl -fspv-debug=vulkan
// CHECK: [[mainName:%[0-9]+]] = OpString "wrapper"
// CHECK: [[clOpts:%[0-9]+]] = OpString " -E main -T ps_6_0 -spirv -fcgl -fspv-debug=vulkan
// CHECK: [[srcMainName:%[0-9]+]] = OpString "main"
// CHECK: [[int:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 %uint_4 %uint_0
// CHECK: [[float:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 %uint_3 %uint_0
@ -17,18 +18,24 @@
// Check DebugFunction instructions
//
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugFunction [[fooName]] [[fooFnType]] [[source]] %uint_34 %uint_1 [[compilationUnit]] [[emptyStr]] %uint_3 %uint_35
// CHECK: [[mainFnType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeFunction %uint_3 %void
// CHECK: [[mainDbgFn:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[mainName]] [[mainFnType]] [[source]] %uint_46 %uint_1 [[compilationUnit]] [[emptyStr]] %uint_3 %uint_47
// CHECK: [[float4:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeVector [[float]] %uint_4
// CHECK: [[mainFnType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeFunction %uint_3 [[float4]] [[float4]]
// CHECK: [[mainDbgFn:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[mainName]] [[mainFnType]] [[source]] %uint_39 %uint_1 [[compilationUnit]] [[emptyStr]] %uint_3 %uint_40
// CHECK: [[srcMainFnType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeFunction %uint_3 [[float4]] [[float4]]
// CHECK: [[srcMainDbgFn:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[srcMainName]] [[srcMainFnType]] [[source]] %uint_46 %uint_1 [[compilationUnit]] [[emptyStr]] %uint_3 %uint_47
// CHECK: [[mainDbgEp:%[0-9]+]] = OpExtInst %void [[set]] DebugEntryPoint [[mainDbgFn]] [[compilationUnit]] {{%[0-9]+}} [[clOpts]]
// Check DebugFunctionDefintion is in src_main
// Check DebugFunctionDefinition is in main
//
// CHECK: %main = OpFunction %void None {{%[0-9]+}}
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugFunctionDefinition [[mainDbgFn]] %main
// CHECK: OpFunctionEnd
// Check DebugFunctionDefinition is in src.main
//
// CHECK: %src_main = OpFunction %v4float None {{%[0-9]+}}
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugFunctionDefinition [[mainDbgFn]] %src_main
// CHECK: OpFunctionEnd
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[srcMainDbgFn]]
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugFunctionDefinition [[srcMainDbgFn]] %src_main
// CHECK: OpFunctionEnd
void foo(int x, float y)