SPV: Reduce spurious type generation by removing intermediate types in the middle of access chains.
This generally simplifies access chain generation, with far fewer type conversions.
It is particularly important to future SPIR-V changes where there is less aggregate
type uniqueness due to carrying different layout information with the type.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 4c7c17c..0240dea 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -530,12 +530,12 @@
// evaluate the right
builder.clearAccessChain();
node->getRight()->traverse(this);
- spv::Id rValue = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
+ spv::Id rValue = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType()));
if (node->getOp() != glslang::EOpAssign) {
// the left is also an r-value
builder.setAccessChain(lValue);
- spv::Id leftRValue = builder.accessChainLoad(TranslatePrecisionDecoration(node->getLeft()->getType()));
+ spv::Id leftRValue = builder.accessChainLoad(convertGlslangToSpvType(node->getLeft()->getType()));
// do the operation
rValue = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getType()),
@@ -587,10 +587,10 @@
// so short circuit the access-chain stuff with a swizzle.
std::vector<unsigned> swizzle;
swizzle.push_back(node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst());
- builder.accessChainPushSwizzle(swizzle);
+ builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()));
} else {
// normal case for indexing array or structure or block
- builder.accessChainPush(builder.makeIntConstant(index), convertGlslangToSpvType(node->getType()));
+ builder.accessChainPush(builder.makeIntConstant(index));
}
}
return false;
@@ -611,15 +611,15 @@
// compute the next index in the chain
builder.clearAccessChain();
node->getRight()->traverse(this);
- spv::Id index = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
+ spv::Id index = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType()));
// restore the saved access chain
builder.setAccessChain(partial);
if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector())
- builder.accessChainPushComponent(index);
+ builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()));
else
- builder.accessChainPush(index, convertGlslangToSpvType(node->getType()));
+ builder.accessChainPush(index);
}
return false;
case glslang::EOpVectorSwizzle:
@@ -629,7 +629,7 @@
std::vector<unsigned> swizzle;
for (int i = 0; i < (int)swizzleSequence.size(); ++i)
swizzle.push_back(swizzleSequence[i]->getAsConstantUnion()->getConstArray()[0].getIConst());
- builder.accessChainPushSwizzle(swizzle);
+ builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()));
}
return false;
default:
@@ -641,11 +641,11 @@
// Get the operands
builder.clearAccessChain();
node->getLeft()->traverse(this);
- spv::Id left = builder.accessChainLoad(TranslatePrecisionDecoration(node->getLeft()->getType()));
+ spv::Id left = builder.accessChainLoad(convertGlslangToSpvType(node->getLeft()->getType()));
builder.clearAccessChain();
node->getRight()->traverse(this);
- spv::Id right = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType()));
+ spv::Id right = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType()));
spv::Id result;
spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
@@ -702,7 +702,7 @@
builder.clearAccessChain();
node->getOperand()->traverse(this);
- spv::Id operand = builder.accessChainLoad(TranslatePrecisionDecoration(node->getOperand()->getType()));
+ spv::Id operand = builder.accessChainLoad(convertGlslangToSpvType(node->getOperand()->getType()));
spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
@@ -1038,11 +1038,11 @@
builder.clearAccessChain();
left->traverse(this);
- spv::Id leftId = builder.accessChainLoad(TranslatePrecisionDecoration(left->getType()));
+ spv::Id leftId = builder.accessChainLoad(convertGlslangToSpvType(left->getType()));
builder.clearAccessChain();
right->traverse(this);
- spv::Id rightId = builder.accessChainLoad(TranslatePrecisionDecoration(right->getType()));
+ spv::Id rightId = builder.accessChainLoad(convertGlslangToSpvType(right->getType()));
result = createBinaryOperation(binOp, precision,
convertGlslangToSpvType(node->getType()), leftId, rightId,
@@ -1084,7 +1084,7 @@
if (lvalue)
operands.push_back(builder.accessChainGetLValue());
else
- operands.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangOperands[arg]->getAsTyped()->getType())));
+ operands.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangOperands[arg]->getAsTyped()->getType())));
}
if (atomic) {
@@ -1134,13 +1134,13 @@
node->getCondition()->traverse(this);
// make an "if" based on the value created by the condition
- spv::Builder::If ifBuilder(builder.accessChainLoad(spv::NoPrecision), builder);
+ spv::Builder::If ifBuilder(builder.accessChainLoad(convertGlslangToSpvType(node->getCondition()->getType())), builder);
if (node->getTrueBlock()) {
// emit the "then" statement
node->getTrueBlock()->traverse(this);
if (result)
- builder.createStore(builder.accessChainLoad(TranslatePrecisionDecoration(node->getTrueBlock()->getAsTyped()->getType())), result);
+ builder.createStore(builder.accessChainLoad(convertGlslangToSpvType(node->getTrueBlock()->getAsTyped()->getType())), result);
}
if (node->getFalseBlock()) {
@@ -1148,7 +1148,7 @@
// emit the "else" statement
node->getFalseBlock()->traverse(this);
if (result)
- builder.createStore(builder.accessChainLoad(TranslatePrecisionDecoration(node->getFalseBlock()->getAsTyped()->getType())), result);
+ builder.createStore(builder.accessChainLoad(convertGlslangToSpvType(node->getFalseBlock()->getAsTyped()->getType())), result);
}
ifBuilder.makeEndIf();
@@ -1169,7 +1169,7 @@
{
// emit and get the condition before doing anything with switch
node->getCondition()->traverse(this);
- spv::Id selector = builder.accessChainLoad(TranslatePrecisionDecoration(node->getCondition()->getAsTyped()->getType()));
+ spv::Id selector = builder.accessChainLoad(convertGlslangToSpvType(node->getCondition()->getAsTyped()->getType()));
// browse the children to sort out code segments
int defaultSegment = -1;
@@ -1233,7 +1233,7 @@
if (node->getTest()) {
node->getTest()->traverse(this);
// the AST only contained the test computation, not the branch, we have to add it
- spv::Id condition = builder.accessChainLoad(TranslatePrecisionDecoration(node->getTest()->getType()));
+ spv::Id condition = builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType()));
builder.createLoopTestBranch(condition);
} else {
builder.createBranchToBody();
@@ -1279,7 +1279,7 @@
if (inMain)
builder.makeMainReturn();
else if (node->getExpression())
- builder.makeReturn(false, builder.accessChainLoad(TranslatePrecisionDecoration(node->getExpression()->getType())));
+ builder.makeReturn(false, builder.accessChainLoad(convertGlslangToSpvType(node->getExpression()->getType())));
else
builder.makeReturn();
@@ -1664,7 +1664,7 @@
for (int i = 0; i < (int)glslangArguments.size(); ++i) {
builder.clearAccessChain();
glslangArguments[i]->traverse(this);
- arguments.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangArguments[i]->getAsTyped()->getType())));
+ arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangArguments[i]->getAsTyped()->getType())));
}
}
@@ -1672,7 +1672,7 @@
{
builder.clearAccessChain();
node.getOperand()->traverse(this);
- arguments.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(node.getAsTyped()->getType())));
+ arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(node.getOperand()->getType())));
}
spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermOperator* node)
@@ -1806,17 +1806,19 @@
// 1. Evaluate the arguments
std::vector<spv::Builder::AccessChain> lValues;
std::vector<spv::Id> rValues;
+ std::vector<spv::Id> argTypes;
for (int a = 0; a < (int)glslangArgs.size(); ++a) {
// build l-value
builder.clearAccessChain();
glslangArgs[a]->traverse(this);
+ argTypes.push_back(convertGlslangToSpvType(glslangArgs[a]->getAsTyped()->getType()));
// keep outputs as l-values, evaluate input-only as r-values
if (qualifiers[a] != glslang::EvqConstReadOnly) {
// save l-value
lValues.push_back(builder.getAccessChain());
} else {
// process r-value
- rValues.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangArgs[a]->getAsTyped()->getType())));
+ rValues.push_back(builder.accessChainLoad(argTypes.back()));
}
}
@@ -1836,7 +1838,7 @@
if (qualifiers[a] == glslang::EvqIn || qualifiers[a] == glslang::EvqInOut) {
// need to copy the input into output space
builder.setAccessChain(lValues[lValueCount]);
- spv::Id copy = builder.accessChainLoad(spv::NoPrecision); // TODO: get precision
+ spv::Id copy = builder.accessChainLoad(argTypes[a]);
builder.createStore(copy, arg);
}
++lValueCount;