Skip to content

Commit

Permalink
[SPIRV] Register all decls for a variable. (#6969)
Browse files Browse the repository at this point in the history
Some variable can have multiple decls. In one case, there could be a
declaration of a const static member variable that is later defined. All
of these decls need to be in astDecls and associated with the same
variable.

The current code will only add the decl for the defintion. This leads to
problems when trying to find the variable for the declaration.

Fixes #6787
  • Loading branch information
s-perron authored Oct 21, 2024
1 parent c6d98ef commit 16e6727
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 13 deletions.
41 changes: 28 additions & 13 deletions tools/clang/lib/SPIRV/DeclResultIdMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,7 @@ DeclResultIdMapper::createFnParam(const ParmVarDecl *param,
fnParamInstr->setContainsAliasComponent(isAlias);

assert(astDecls[param].instr == nullptr);
astDecls[param].instr = fnParamInstr;
registerVariableForDecl(param, fnParamInstr);

if (spirvOptions.debugInfoRich) {
// Add DebugLocalVariable information
Expand Down Expand Up @@ -1100,7 +1100,7 @@ DeclResultIdMapper::createFnVar(const VarDecl *var,
bool isAlias = false;
(void)getTypeAndCreateCounterForPotentialAliasVar(var, &isAlias);
varInstr->setContainsAliasComponent(isAlias);
astDecls[var].instr = varInstr;
registerVariableForDecl(var, varInstr);
return varInstr;
}

Expand Down Expand Up @@ -1145,7 +1145,7 @@ DeclResultIdMapper::createFileVar(const VarDecl *var,
bool isAlias = false;
(void)getTypeAndCreateCounterForPotentialAliasVar(var, &isAlias);
varInstr->setContainsAliasComponent(isAlias);
astDecls[var].instr = varInstr;
registerVariableForDecl(var, varInstr);

createDebugGlobalVariable(varInstr, type, loc, name);

Expand Down Expand Up @@ -1267,7 +1267,7 @@ SpirvVariable *DeclResultIdMapper::createExternVar(const VarDecl *var,
}
}

astDecls[var] = createDeclSpirvInfo(varInstr);
registerVariableForDecl(var, createDeclSpirvInfo(varInstr));

createDebugGlobalVariable(varInstr, type, loc, name);

Expand Down Expand Up @@ -1305,7 +1305,7 @@ SpirvInstruction *DeclResultIdMapper::createResultId(const VarDecl *var) {
}

SpirvInstruction *init = theEmitter.doExpr(var->getInit());
astDecls[var] = createDeclSpirvInfo(init);
registerVariableForDecl(var, createDeclSpirvInfo(init));
return init;
}

Expand All @@ -1324,7 +1324,7 @@ DeclResultIdMapper::createOrUpdateStringVar(const VarDecl *var) {
const StringLiteral *stringLiteral =
dyn_cast<StringLiteral>(var->getInit()->IgnoreParenCasts());
SpirvString *init = spvBuilder.getString(stringLiteral->getString());
astDecls[var] = createDeclSpirvInfo(init);
registerVariableForDecl(var, createDeclSpirvInfo(init));
return init;
}

Expand Down Expand Up @@ -1483,7 +1483,7 @@ SpirvVariable *DeclResultIdMapper::createCTBuffer(const HLSLBufferDecl *decl) {
if (isResourceType(varDecl->getType()))
continue;

astDecls[varDecl] = createDeclSpirvInfo(bufferVar, index++);
registerVariableForDecl(varDecl, createDeclSpirvInfo(bufferVar, index++));
}
// If it does not contains a member with non-resource type, we do not want to
// set a dedicated binding number.
Expand Down Expand Up @@ -1549,7 +1549,7 @@ SpirvVariable *DeclResultIdMapper::createPushConstant(const VarDecl *decl) {
}

// Register the VarDecl
astDecls[decl] = createDeclSpirvInfo(var);
registerVariableForDecl(decl, createDeclSpirvInfo(var));

// Do not push this variable into resourceVars since it does not need
// descriptor set.
Expand Down Expand Up @@ -1600,7 +1600,7 @@ DeclResultIdMapper::createShaderRecordBuffer(const VarDecl *decl,
}

// Register the VarDecl
astDecls[decl] = createDeclSpirvInfo(var);
registerVariableForDecl(decl, createDeclSpirvInfo(var));

// Do not push this variable into resourceVars since it does not need
// descriptor set.
Expand Down Expand Up @@ -1638,7 +1638,7 @@ DeclResultIdMapper::createShaderRecordBuffer(const HLSLBufferDecl *decl,
if (isResourceType(varDecl->getType()))
continue;

astDecls[varDecl] = createDeclSpirvInfo(bufferVar, index++);
registerVariableForDecl(varDecl, createDeclSpirvInfo(bufferVar, index++));
}
return bufferVar;
}
Expand Down Expand Up @@ -1688,7 +1688,7 @@ void DeclResultIdMapper::createGlobalsCBuffer(const VarDecl *var) {
if (isResourceType(varDecl->getType()))
continue;

astDecls[varDecl] = createDeclSpirvInfo(globals, index++);
registerVariableForDecl(varDecl, createDeclSpirvInfo(globals, index++));
}
}

Expand Down Expand Up @@ -1801,7 +1801,7 @@ DeclResultIdMapper::getCounterVarFields(const DeclaratorDecl *decl) {
void DeclResultIdMapper::registerSpecConstant(const VarDecl *decl,
SpirvInstruction *specConstant) {
specConstant->setRValue();
astDecls[decl] = createDeclSpirvInfo(specConstant);
registerVariableForDecl(decl, createDeclSpirvInfo(specConstant));
}

void DeclResultIdMapper::createCounterVar(
Expand Down Expand Up @@ -4817,7 +4817,7 @@ void DeclResultIdMapper::tryToCreateImplicitConstVar(const ValueDecl *decl) {
SpirvInstruction *constVal =
spvBuilder.getConstantInt(astContext.UnsignedIntTy, val->getInt());
constVal->setRValue(true);
astDecls[varDecl].instr = constVal;
registerVariableForDecl(varDecl, constVal);
}

void DeclResultIdMapper::decorateWithIntrinsicAttrs(
Expand Down Expand Up @@ -4880,6 +4880,21 @@ spv::ExecutionMode DeclResultIdMapper::getInterlockExecutionMode() {
spv::ExecutionMode::PixelInterlockOrderedEXT);
}

void DeclResultIdMapper::registerVariableForDecl(const VarDecl *var,
SpirvInstruction *varInstr) {
DeclSpirvInfo spirvInfo;
spirvInfo.instr = varInstr;
spirvInfo.indexInCTBuffer = -1;
registerVariableForDecl(var, spirvInfo);
}

void DeclResultIdMapper::registerVariableForDecl(const VarDecl *var,
DeclSpirvInfo spirvInfo) {
for (const auto *v : var->redecls()) {
astDecls[v] = spirvInfo;
}
}

void DeclResultIdMapper::copyHullOutStageVarsToOutputPatch(
SpirvInstruction *hullMainOutputPatch, const ParmVarDecl *outputPatchDecl,
QualType outputControlPointType, uint32_t numOutputControlPoints) {
Expand Down
10 changes: 10 additions & 0 deletions tools/clang/lib/SPIRV/DeclResultIdMapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,16 @@ class DeclResultIdMapper {
/// views.
void setInterlockExecutionMode(spv::ExecutionMode mode);

/// \brief Add |varInstr| to |astDecls| for every Decl for the variable |var|.
/// It is possible for a variable to have multiple declarations, and all of
/// them should be associated with the same variable.
void registerVariableForDecl(const VarDecl *var, SpirvInstruction *varInstr);

/// \brief Add |spirvInfo| to |astDecls| for every Decl for the variable
/// |var|. It is possible for a variable to have multiple declarations, and
/// all of them should be associated with the same variable.
void registerVariableForDecl(const VarDecl *var, DeclSpirvInfo spirvInfo);

private:
SpirvBuilder &spvBuilder;
SpirvEmitter &theEmitter;
Expand Down
15 changes: 15 additions & 0 deletions tools/clang/test/CodeGenSPIRV/static_member_var.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// RUN: %dxc -T ps_6_6 -E PSMain %s -spirv | FileCheck %s

struct PSInput
{
static const uint Val;
uint Func() { return Val; }
};

static const uint PSInput::Val = 3;

// CHECK: OpStore %out_var_SV_Target0 %uint_3
uint PSMain(PSInput input) : SV_Target0
{
return input.Func();
}

0 comments on commit 16e6727

Please sign in to comment.