Skip to content

Commit da30696

Browse files
authored
Memoize types in spirv asm blocks (shader-slang#3215)
* Neaten emitInst * Memoize types in spirv asm blocks * less expected failure
1 parent 6542d47 commit da30696

File tree

2 files changed

+82
-20
lines changed

2 files changed

+82
-20
lines changed

source/slang/slang-emit-spirv.cpp

+82-19
Original file line numberDiff line numberDiff line change
@@ -978,11 +978,12 @@ struct SPIRVEmitContext
978978
template<typename... Operands>
979979
SpvInst* emitInst(SpvInstParent* parent, IRInst* irInst, SpvOp opcode, const Operands& ...ops)
980980
{
981-
InstConstructScope scopeInst(this, opcode, irInst);
982-
SpvInst* spvInst = scopeInst;
983-
(emitOperand(ops), ...);
984-
parent->addInst(spvInst);
985-
return spvInst;
981+
return emitInstCustomOperandFunc(
982+
parent,
983+
irInst,
984+
opcode,
985+
[&](){(emitOperand(ops), ...);}
986+
);
986987
}
987988

988989
template<typename OperandEmitFunc>
@@ -1008,11 +1009,31 @@ struct SPIRVEmitContext
10081009
ResultIDToken resultId,
10091010
const Operands& ...ops
10101011
)
1012+
{
1013+
return emitInstMemoizedCustomOperandFunc(
1014+
parent,
1015+
irInst,
1016+
opcode,
1017+
resultId,
1018+
[&](){(emitOperand(ops), ...);}
1019+
);
1020+
}
1021+
1022+
template<typename OperandEmitFunc>
1023+
SpvInst* emitInstMemoizedCustomOperandFunc(
1024+
SpvInstParent* parent,
1025+
IRInst* irInst,
1026+
SpvOp opcode,
1027+
// We take the resultId here explicitly here to make sure we don't try
1028+
// and memoize its value.
1029+
ResultIDToken resultId,
1030+
const OperandEmitFunc& f
1031+
)
10111032
{
10121033
List<SpvWord> ourOperands;
10131034
{
10141035
auto scopePeek = OperandMemoizeScope(this);
1015-
(emitOperand(ops), ...);
1036+
f();
10161037
// Steal our operands back, so we don't have to calculate them
10171038
// again
10181039
ourOperands = std::move(m_operandStack);
@@ -4187,21 +4208,63 @@ struct SPIRVEmitContext
41874208
default:
41884209
break;
41894210
}
4211+
const auto opParent = parentForOpCode(opcode, parent);
4212+
const auto opInfo = m_grammarInfo->opInfos.lookup(opcode);
4213+
4214+
// TODO: handle resultIdIndex == 1, for constants
4215+
const bool memoize = opParent == getSection(SpvLogicalSectionID::ConstantsAndTypes)
4216+
&& opInfo && opInfo->resultIdIndex == 0;
4217+
4218+
// We want the "result instruction" to refer to the top level
4219+
// block which assumes its value, the others are free to refer
4220+
// to whatever, so just use the internal spv inst rep
4221+
// TODO: This is not correct, because the instruction which is
4222+
// assigned to result is not necessarily the last instruction
4223+
const auto assignedInst = isLast ? as<IRInst>(inst) : spvInst;
41904224

4191-
last = emitInstCustomOperandFunc(
4192-
parentForOpCode(opcode, parent),
4193-
// We want the "result instruction" to refer to the top level
4194-
// block which assumes its value, the others are free to refer
4195-
// to whatever, so just use the internal spv inst rep
4196-
// TODO: This is not correct, because the instruction which is
4197-
// assigned to result is not necessarily the last instruction
4198-
isLast ? as<IRInst>(inst) : spvInst,
4199-
opcode,
4200-
[&](){
4201-
for(const auto operand : spvInst->getSPIRVOperands())
4202-
emitSpvAsmOperand(operand);
4225+
if(memoize)
4226+
{
4227+
last = emitInstMemoizedCustomOperandFunc(
4228+
opParent,
4229+
assignedInst,
4230+
opcode,
4231+
kResultID,
4232+
[&](){
4233+
Index i = 0;
4234+
for(const auto operand : spvInst->getSPIRVOperands()) {
4235+
if(i++ != 0)
4236+
emitSpvAsmOperand(operand);
4237+
};
4238+
}
4239+
);
4240+
4241+
// The result operand is the one at index 1, after the
4242+
// opcode itself.
4243+
// If this happens to be an "id" operand, then we need to
4244+
// correct the Id we have stored in our map with the actual
4245+
// memoized result. This is safe because a condition on
4246+
// memoized instructions is that they come before their
4247+
// uses.
4248+
const auto resOperand = cast<IRSPIRVAsmOperand>(spvInst->getOperand(1));
4249+
if(resOperand->getOp() == kIROp_SPIRVAsmOperandId)
4250+
{
4251+
const auto idName =
4252+
cast<IRStringLit>(resOperand->getValue())->getStringSlice();
4253+
idMap[idName] = last->id;
42034254
}
4204-
);
4255+
}
4256+
else
4257+
{
4258+
emitInstCustomOperandFunc(
4259+
opParent,
4260+
assignedInst,
4261+
opcode,
4262+
[&](){
4263+
for(const auto operand : spvInst->getSPIRVOperands())
4264+
emitSpvAsmOperand(operand);
4265+
}
4266+
);
4267+
}
42054268
}
42064269
}
42074270

tests/expected-failure.txt

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
tests/language-feature/constants/constexpr-loop.slang.1 (vk)
21
tests/optimization/func-resource-result/func-resource-result-complex.slang.1 (vk)
32
tests/type/texture-sampler/texture-sampler-2d.slang (vk)
43
tests/hlsl-intrinsic/texture-lod-shadow.slang.1

0 commit comments

Comments
 (0)