Skip to content

Commit 16e6727

Browse files
authored
[SPIRV] Register all decls for a variable. (#6969)
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
1 parent c6d98ef commit 16e6727

File tree

3 files changed

+53
-13
lines changed

3 files changed

+53
-13
lines changed

tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,7 @@ DeclResultIdMapper::createFnParam(const ParmVarDecl *param,
10511051
fnParamInstr->setContainsAliasComponent(isAlias);
10521052

10531053
assert(astDecls[param].instr == nullptr);
1054-
astDecls[param].instr = fnParamInstr;
1054+
registerVariableForDecl(param, fnParamInstr);
10551055

10561056
if (spirvOptions.debugInfoRich) {
10571057
// Add DebugLocalVariable information
@@ -1100,7 +1100,7 @@ DeclResultIdMapper::createFnVar(const VarDecl *var,
11001100
bool isAlias = false;
11011101
(void)getTypeAndCreateCounterForPotentialAliasVar(var, &isAlias);
11021102
varInstr->setContainsAliasComponent(isAlias);
1103-
astDecls[var].instr = varInstr;
1103+
registerVariableForDecl(var, varInstr);
11041104
return varInstr;
11051105
}
11061106

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

11501150
createDebugGlobalVariable(varInstr, type, loc, name);
11511151

@@ -1267,7 +1267,7 @@ SpirvVariable *DeclResultIdMapper::createExternVar(const VarDecl *var,
12671267
}
12681268
}
12691269

1270-
astDecls[var] = createDeclSpirvInfo(varInstr);
1270+
registerVariableForDecl(var, createDeclSpirvInfo(varInstr));
12711271

12721272
createDebugGlobalVariable(varInstr, type, loc, name);
12731273

@@ -1305,7 +1305,7 @@ SpirvInstruction *DeclResultIdMapper::createResultId(const VarDecl *var) {
13051305
}
13061306

13071307
SpirvInstruction *init = theEmitter.doExpr(var->getInit());
1308-
astDecls[var] = createDeclSpirvInfo(init);
1308+
registerVariableForDecl(var, createDeclSpirvInfo(init));
13091309
return init;
13101310
}
13111311

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

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

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

15511551
// Register the VarDecl
1552-
astDecls[decl] = createDeclSpirvInfo(var);
1552+
registerVariableForDecl(decl, createDeclSpirvInfo(var));
15531553

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

16021602
// Register the VarDecl
1603-
astDecls[decl] = createDeclSpirvInfo(var);
1603+
registerVariableForDecl(decl, createDeclSpirvInfo(var));
16041604

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

1641-
astDecls[varDecl] = createDeclSpirvInfo(bufferVar, index++);
1641+
registerVariableForDecl(varDecl, createDeclSpirvInfo(bufferVar, index++));
16421642
}
16431643
return bufferVar;
16441644
}
@@ -1688,7 +1688,7 @@ void DeclResultIdMapper::createGlobalsCBuffer(const VarDecl *var) {
16881688
if (isResourceType(varDecl->getType()))
16891689
continue;
16901690

1691-
astDecls[varDecl] = createDeclSpirvInfo(globals, index++);
1691+
registerVariableForDecl(varDecl, createDeclSpirvInfo(globals, index++));
16921692
}
16931693
}
16941694

@@ -1801,7 +1801,7 @@ DeclResultIdMapper::getCounterVarFields(const DeclaratorDecl *decl) {
18011801
void DeclResultIdMapper::registerSpecConstant(const VarDecl *decl,
18021802
SpirvInstruction *specConstant) {
18031803
specConstant->setRValue();
1804-
astDecls[decl] = createDeclSpirvInfo(specConstant);
1804+
registerVariableForDecl(decl, createDeclSpirvInfo(specConstant));
18051805
}
18061806

18071807
void DeclResultIdMapper::createCounterVar(
@@ -4817,7 +4817,7 @@ void DeclResultIdMapper::tryToCreateImplicitConstVar(const ValueDecl *decl) {
48174817
SpirvInstruction *constVal =
48184818
spvBuilder.getConstantInt(astContext.UnsignedIntTy, val->getInt());
48194819
constVal->setRValue(true);
4820-
astDecls[varDecl].instr = constVal;
4820+
registerVariableForDecl(varDecl, constVal);
48214821
}
48224822

48234823
void DeclResultIdMapper::decorateWithIntrinsicAttrs(
@@ -4880,6 +4880,21 @@ spv::ExecutionMode DeclResultIdMapper::getInterlockExecutionMode() {
48804880
spv::ExecutionMode::PixelInterlockOrderedEXT);
48814881
}
48824882

4883+
void DeclResultIdMapper::registerVariableForDecl(const VarDecl *var,
4884+
SpirvInstruction *varInstr) {
4885+
DeclSpirvInfo spirvInfo;
4886+
spirvInfo.instr = varInstr;
4887+
spirvInfo.indexInCTBuffer = -1;
4888+
registerVariableForDecl(var, spirvInfo);
4889+
}
4890+
4891+
void DeclResultIdMapper::registerVariableForDecl(const VarDecl *var,
4892+
DeclSpirvInfo spirvInfo) {
4893+
for (const auto *v : var->redecls()) {
4894+
astDecls[v] = spirvInfo;
4895+
}
4896+
}
4897+
48834898
void DeclResultIdMapper::copyHullOutStageVarsToOutputPatch(
48844899
SpirvInstruction *hullMainOutputPatch, const ParmVarDecl *outputPatchDecl,
48854900
QualType outputControlPointType, uint32_t numOutputControlPoints) {

tools/clang/lib/SPIRV/DeclResultIdMapper.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,16 @@ class DeclResultIdMapper {
981981
/// views.
982982
void setInterlockExecutionMode(spv::ExecutionMode mode);
983983

984+
/// \brief Add |varInstr| to |astDecls| for every Decl for the variable |var|.
985+
/// It is possible for a variable to have multiple declarations, and all of
986+
/// them should be associated with the same variable.
987+
void registerVariableForDecl(const VarDecl *var, SpirvInstruction *varInstr);
988+
989+
/// \brief Add |spirvInfo| to |astDecls| for every Decl for the variable
990+
/// |var|. It is possible for a variable to have multiple declarations, and
991+
/// all of them should be associated with the same variable.
992+
void registerVariableForDecl(const VarDecl *var, DeclSpirvInfo spirvInfo);
993+
984994
private:
985995
SpirvBuilder &spvBuilder;
986996
SpirvEmitter &theEmitter;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %dxc -T ps_6_6 -E PSMain %s -spirv | FileCheck %s
2+
3+
struct PSInput
4+
{
5+
static const uint Val;
6+
uint Func() { return Val; }
7+
};
8+
9+
static const uint PSInput::Val = 3;
10+
11+
// CHECK: OpStore %out_var_SV_Target0 %uint_3
12+
uint PSMain(PSInput input) : SV_Target0
13+
{
14+
return input.Func();
15+
}

0 commit comments

Comments
 (0)