SPV: only declare the pure 8/16-bit capabilities when needed.

Only when operations stray outside the 8/16-bit storage-capabilities
are the general (pure 8/16-bit) capabilities needed.
This commit is contained in:
John Kessenich 2018-08-15 13:54:09 -06:00
parent 149afc3930
commit 31aa3d6019
10 changed files with 125 additions and 29 deletions

View file

@ -194,10 +194,8 @@ Id Builder::makeIntegerType(int width, bool hasSign)
// deal with capabilities
switch (width) {
case 8:
addCapability(CapabilityInt8);
break;
case 16:
addCapability(CapabilityInt16);
// these are currently handled by storage-type declarations and post processing
break;
case 64:
addCapability(CapabilityInt64);
@ -229,7 +227,7 @@ Id Builder::makeFloatType(int width)
// deal with capabilities
switch (width) {
case 16:
addCapability(CapabilityFloat16);
// currently handled by storage-type declarations and post processing
break;
case 64:
addCapability(CapabilityFloat64);
@ -520,12 +518,6 @@ Op Builder::getMostBasicTypeClass(Id typeId) const
Op typeClass = instr->getOpCode();
switch (typeClass)
{
case OpTypeVoid:
case OpTypeBool:
case OpTypeInt:
case OpTypeFloat:
case OpTypeStruct:
return typeClass;
case OpTypeVector:
case OpTypeMatrix:
case OpTypeArray:
@ -534,8 +526,7 @@ Op Builder::getMostBasicTypeClass(Id typeId) const
case OpTypePointer:
return getMostBasicTypeClass(instr->getIdOperand(1));
default:
assert(0);
return OpTypeFloat;
return typeClass;
}
}
@ -622,6 +613,36 @@ Id Builder::getContainedTypeId(Id typeId) const
return getContainedTypeId(typeId, 0);
}
// Returns true if 'typeId' is or contains a scalar type declared with 'typeOp'
// of width 'width'. The 'width' is only consumed for int and float types.
// Returns false otherwise.
bool Builder::containsType(Id typeId, spv::Op typeOp, int width) const
{
const Instruction& instr = *module.getInstruction(typeId);
Op typeClass = instr.getOpCode();
switch (typeClass)
{
case OpTypeInt:
case OpTypeFloat:
return typeClass == typeOp && instr.getImmediateOperand(0) == width;
case OpTypeStruct:
for (int m = 0; m < instr.getNumOperands(); ++m) {
if (containsType(instr.getIdOperand(m), typeOp, width))
return true;
}
return false;
case OpTypeVector:
case OpTypeMatrix:
case OpTypeArray:
case OpTypeRuntimeArray:
case OpTypePointer:
return containsType(getContainedTypeId(typeId), typeOp, width);
default:
return typeClass == typeOp;
}
}
// See if a scalar constant of this type has already been created, so it
// can be reused rather than duplicated. (Required by the specification).
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value)