Commit 738314fe by Dejan Mircevski

Revert SpvBuilder.* to master versions.

parent e5926526
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
#include "SpvBuilder.h" #include "SpvBuilder.h"
#ifndef _WIN32 #ifndef _WIN32
#include <cstdio> #include <cstdio>
#endif #endif
namespace spv { namespace spv {
...@@ -67,12 +67,15 @@ Builder::Builder(unsigned int magicNumber, SpvBuildLogger* buildLogger) : ...@@ -67,12 +67,15 @@ Builder::Builder(unsigned int magicNumber, SpvBuildLogger* buildLogger) :
clearAccessChain(); clearAccessChain();
} }
Builder::~Builder() {} Builder::~Builder()
{
}
Id Builder::import(const char* name) Id Builder::import(const char* name)
{ {
Instruction* import = new Instruction(getUniqueId(), NoType, OpExtInstImport); Instruction* import = new Instruction(getUniqueId(), NoType, OpExtInstImport);
import->addStringOperand(name); import->addStringOperand(name);
imports.push_back(std::unique_ptr<Instruction>(import)); imports.push_back(std::unique_ptr<Instruction>(import));
return import->getResultId(); return import->getResultId();
} }
...@@ -81,8 +84,7 @@ Id Builder::import(const char* name) ...@@ -81,8 +84,7 @@ Id Builder::import(const char* name)
Id Builder::makeVoidType() Id Builder::makeVoidType()
{ {
Instruction* type; Instruction* type;
if (groupedTypes[OpTypeVoid].size() == 0) if (groupedTypes[OpTypeVoid].size() == 0) {
{
type = new Instruction(getUniqueId(), NoType, OpTypeVoid); type = new Instruction(getUniqueId(), NoType, OpTypeVoid);
groupedTypes[OpTypeVoid].push_back(type); groupedTypes[OpTypeVoid].push_back(type);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type)); constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
...@@ -96,8 +98,7 @@ Id Builder::makeVoidType() ...@@ -96,8 +98,7 @@ Id Builder::makeVoidType()
Id Builder::makeBoolType() Id Builder::makeBoolType()
{ {
Instruction* type; Instruction* type;
if (groupedTypes[OpTypeBool].size() == 0) if (groupedTypes[OpTypeBool].size() == 0) {
{
type = new Instruction(getUniqueId(), NoType, OpTypeBool); type = new Instruction(getUniqueId(), NoType, OpTypeBool);
groupedTypes[OpTypeBool].push_back(type); groupedTypes[OpTypeBool].push_back(type);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type)); constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
...@@ -111,8 +112,7 @@ Id Builder::makeBoolType() ...@@ -111,8 +112,7 @@ Id Builder::makeBoolType()
Id Builder::makeSamplerType() Id Builder::makeSamplerType()
{ {
Instruction* type; Instruction* type;
if (groupedTypes[OpTypeSampler].size() == 0) if (groupedTypes[OpTypeSampler].size() == 0) {
{
type = new Instruction(getUniqueId(), NoType, OpTypeSampler); type = new Instruction(getUniqueId(), NoType, OpTypeSampler);
groupedTypes[OpTypeSampler].push_back(type); groupedTypes[OpTypeSampler].push_back(type);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type)); constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
...@@ -127,8 +127,7 @@ Id Builder::makePointer(StorageClass storageClass, Id pointee) ...@@ -127,8 +127,7 @@ Id Builder::makePointer(StorageClass storageClass, Id pointee)
{ {
// try to find it // try to find it
Instruction* type; Instruction* type;
for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
{
type = groupedTypes[OpTypePointer][t]; type = groupedTypes[OpTypePointer][t];
if (type->getImmediateOperand(0) == (unsigned)storageClass && if (type->getImmediateOperand(0) == (unsigned)storageClass &&
type->getIdOperand(1) == pointee) type->getIdOperand(1) == pointee)
...@@ -150,8 +149,7 @@ Id Builder::makeIntegerType(int width, bool hasSign) ...@@ -150,8 +149,7 @@ Id Builder::makeIntegerType(int width, bool hasSign)
{ {
// try to find it // try to find it
Instruction* type; Instruction* type;
for (int t = 0; t < (int)groupedTypes[OpTypeInt].size(); ++t) for (int t = 0; t < (int)groupedTypes[OpTypeInt].size(); ++t) {
{
type = groupedTypes[OpTypeInt][t]; type = groupedTypes[OpTypeInt][t];
if (type->getImmediateOperand(0) == (unsigned)width && if (type->getImmediateOperand(0) == (unsigned)width &&
type->getImmediateOperand(1) == (hasSign ? 1u : 0u)) type->getImmediateOperand(1) == (hasSign ? 1u : 0u))
...@@ -167,8 +165,7 @@ Id Builder::makeIntegerType(int width, bool hasSign) ...@@ -167,8 +165,7 @@ Id Builder::makeIntegerType(int width, bool hasSign)
module.mapInstruction(type); module.mapInstruction(type);
// deal with capabilities // deal with capabilities
switch (width) switch (width) {
{
case 16: case 16:
addCapability(CapabilityInt16); addCapability(CapabilityInt16);
break; break;
...@@ -186,8 +183,7 @@ Id Builder::makeFloatType(int width) ...@@ -186,8 +183,7 @@ Id Builder::makeFloatType(int width)
{ {
// try to find it // try to find it
Instruction* type; Instruction* type;
for (int t = 0; t < (int)groupedTypes[OpTypeFloat].size(); ++t) for (int t = 0; t < (int)groupedTypes[OpTypeFloat].size(); ++t) {
{
type = groupedTypes[OpTypeFloat][t]; type = groupedTypes[OpTypeFloat][t];
if (type->getImmediateOperand(0) == (unsigned)width) if (type->getImmediateOperand(0) == (unsigned)width)
return type->getResultId(); return type->getResultId();
...@@ -201,8 +197,7 @@ Id Builder::makeFloatType(int width) ...@@ -201,8 +197,7 @@ Id Builder::makeFloatType(int width)
module.mapInstruction(type); module.mapInstruction(type);
// deal with capabilities // deal with capabilities
switch (width) switch (width) {
{
case 16: case 16:
addCapability(CapabilityFloat16); addCapability(CapabilityFloat16);
break; break;
...@@ -243,12 +238,12 @@ Id Builder::makeStructResultType(Id type0, Id type1) ...@@ -243,12 +238,12 @@ Id Builder::makeStructResultType(Id type0, Id type1)
{ {
// try to find it // try to find it
Instruction* type; Instruction* type;
for (int t = 0; t < (int)groupedTypes[OpTypeStruct].size(); ++t) for (int t = 0; t < (int)groupedTypes[OpTypeStruct].size(); ++t) {
{
type = groupedTypes[OpTypeStruct][t]; type = groupedTypes[OpTypeStruct][t];
if (type->getNumOperands() != 2) if (type->getNumOperands() != 2)
continue; continue;
if (type->getIdOperand(0) != type0 || type->getIdOperand(1) != type1) if (type->getIdOperand(0) != type0 ||
type->getIdOperand(1) != type1)
continue; continue;
return type->getResultId(); return type->getResultId();
} }
...@@ -265,10 +260,10 @@ Id Builder::makeVectorType(Id component, int size) ...@@ -265,10 +260,10 @@ Id Builder::makeVectorType(Id component, int size)
{ {
// try to find it // try to find it
Instruction* type; Instruction* type;
for (int t = 0; t < (int)groupedTypes[OpTypeVector].size(); ++t) for (int t = 0; t < (int)groupedTypes[OpTypeVector].size(); ++t) {
{
type = groupedTypes[OpTypeVector][t]; type = groupedTypes[OpTypeVector][t];
if (type->getIdOperand(0) == component && type->getImmediateOperand(1) == (unsigned)size) if (type->getIdOperand(0) == component &&
type->getImmediateOperand(1) == (unsigned)size)
return type->getResultId(); return type->getResultId();
} }
...@@ -291,10 +286,10 @@ Id Builder::makeMatrixType(Id component, int cols, int rows) ...@@ -291,10 +286,10 @@ Id Builder::makeMatrixType(Id component, int cols, int rows)
// try to find it // try to find it
Instruction* type; Instruction* type;
for (int t = 0; t < (int)groupedTypes[OpTypeMatrix].size(); ++t) for (int t = 0; t < (int)groupedTypes[OpTypeMatrix].size(); ++t) {
{
type = groupedTypes[OpTypeMatrix][t]; type = groupedTypes[OpTypeMatrix][t];
if (type->getIdOperand(0) == column && type->getImmediateOperand(1) == (unsigned)cols) if (type->getIdOperand(0) == column &&
type->getImmediateOperand(1) == (unsigned)cols)
return type->getResultId(); return type->getResultId();
} }
...@@ -316,13 +311,12 @@ Id Builder::makeMatrixType(Id component, int cols, int rows) ...@@ -316,13 +311,12 @@ Id Builder::makeMatrixType(Id component, int cols, int rows)
Id Builder::makeArrayType(Id element, Id sizeId, int stride) Id Builder::makeArrayType(Id element, Id sizeId, int stride)
{ {
Instruction* type; Instruction* type;
if (stride == 0) if (stride == 0) {
{
// try to find existing type // try to find existing type
for (int t = 0; t < (int)groupedTypes[OpTypeArray].size(); ++t) for (int t = 0; t < (int)groupedTypes[OpTypeArray].size(); ++t) {
{
type = groupedTypes[OpTypeArray][t]; type = groupedTypes[OpTypeArray][t];
if (type->getIdOperand(0) == element && type->getIdOperand(1) == sizeId) if (type->getIdOperand(0) == element &&
type->getIdOperand(1) == sizeId)
return type->getResultId(); return type->getResultId();
} }
} }
...@@ -352,22 +346,18 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes) ...@@ -352,22 +346,18 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
{ {
// try to find it // try to find it
Instruction* type; Instruction* type;
for (int t = 0; t < (int)groupedTypes[OpTypeFunction].size(); ++t) for (int t = 0; t < (int)groupedTypes[OpTypeFunction].size(); ++t) {
{
type = groupedTypes[OpTypeFunction][t]; type = groupedTypes[OpTypeFunction][t];
if (type->getIdOperand(0) != returnType || if (type->getIdOperand(0) != returnType || (int)paramTypes.size() != type->getNumOperands() - 1)
(int)paramTypes.size() != type->getNumOperands() - 1)
continue; continue;
bool mismatch = false; bool mismatch = false;
for (int p = 0; p < (int)paramTypes.size(); ++p) for (int p = 0; p < (int)paramTypes.size(); ++p) {
{ if (paramTypes[p] != type->getIdOperand(p + 1)) {
if (paramTypes[p] != type->getIdOperand(p + 1))
{
mismatch = true; mismatch = true;
break; break;
} }
} }
if (!mismatch) if (! mismatch)
return type->getResultId(); return type->getResultId();
} }
...@@ -383,19 +373,17 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes) ...@@ -383,19 +373,17 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
return type->getResultId(); return type->getResultId();
} }
Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format)
unsigned sampled, ImageFormat format)
{ {
// try to find it // try to find it
Instruction* type; Instruction* type;
for (int t = 0; t < (int)groupedTypes[OpTypeImage].size(); ++t) for (int t = 0; t < (int)groupedTypes[OpTypeImage].size(); ++t) {
{
type = groupedTypes[OpTypeImage][t]; type = groupedTypes[OpTypeImage][t];
if (type->getIdOperand(0) == sampledType && if (type->getIdOperand(0) == sampledType &&
type->getImmediateOperand(1) == (unsigned int)dim && type->getImmediateOperand(1) == (unsigned int)dim &&
type->getImmediateOperand(2) == (depth ? 1u : 0u) && type->getImmediateOperand(2) == ( depth ? 1u : 0u) &&
type->getImmediateOperand(3) == (arrayed ? 1u : 0u) && type->getImmediateOperand(3) == (arrayed ? 1u : 0u) &&
type->getImmediateOperand(4) == (ms ? 1u : 0u) && type->getImmediateOperand(4) == ( ms ? 1u : 0u) &&
type->getImmediateOperand(5) == sampled && type->getImmediateOperand(5) == sampled &&
type->getImmediateOperand(6) == (unsigned int)format) type->getImmediateOperand(6) == (unsigned int)format)
return type->getResultId(); return type->getResultId();
...@@ -404,10 +392,10 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo ...@@ -404,10 +392,10 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
// not found, make it // not found, make it
type = new Instruction(getUniqueId(), NoType, OpTypeImage); type = new Instruction(getUniqueId(), NoType, OpTypeImage);
type->addIdOperand(sampledType); type->addIdOperand(sampledType);
type->addImmediateOperand(dim); type->addImmediateOperand( dim);
type->addImmediateOperand(depth ? 1 : 0); type->addImmediateOperand( depth ? 1 : 0);
type->addImmediateOperand(arrayed ? 1 : 0); type->addImmediateOperand(arrayed ? 1 : 0);
type->addImmediateOperand(ms ? 1 : 0); type->addImmediateOperand( ms ? 1 : 0);
type->addImmediateOperand(sampled); type->addImmediateOperand(sampled);
type->addImmediateOperand((unsigned int)format); type->addImmediateOperand((unsigned int)format);
...@@ -416,8 +404,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo ...@@ -416,8 +404,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
module.mapInstruction(type); module.mapInstruction(type);
// deal with capabilities // deal with capabilities
switch (dim) switch (dim) {
{
case DimBuffer: case DimBuffer:
if (sampled) if (sampled)
addCapability(CapabilitySampledBuffer); addCapability(CapabilitySampledBuffer);
...@@ -431,8 +418,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo ...@@ -431,8 +418,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
addCapability(CapabilityImage1D); addCapability(CapabilityImage1D);
break; break;
case DimCube: case DimCube:
if (arrayed) if (arrayed) {
{
if (sampled) if (sampled)
addCapability(CapabilitySampledCubeArray); addCapability(CapabilitySampledCubeArray);
else else
...@@ -452,11 +438,10 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo ...@@ -452,11 +438,10 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
break; break;
} }
if (ms) if (ms) {
{
if (arrayed) if (arrayed)
addCapability(CapabilityImageMSArray); addCapability(CapabilityImageMSArray);
if (!sampled) if (! sampled)
addCapability(CapabilityStorageImageMultisample); addCapability(CapabilityStorageImageMultisample);
} }
...@@ -467,8 +452,7 @@ Id Builder::makeSampledImageType(Id imageType) ...@@ -467,8 +452,7 @@ Id Builder::makeSampledImageType(Id imageType)
{ {
// try to find it // try to find it
Instruction* type; Instruction* type;
for (int t = 0; t < (int)groupedTypes[OpTypeSampledImage].size(); ++t) for (int t = 0; t < (int)groupedTypes[OpTypeSampledImage].size(); ++t) {
{
type = groupedTypes[OpTypeSampledImage][t]; type = groupedTypes[OpTypeSampledImage][t];
if (type->getIdOperand(0) == imageType) if (type->getIdOperand(0) == imageType)
return type->getResultId(); return type->getResultId();
...@@ -597,16 +581,20 @@ Id Builder::getContainedTypeId(Id typeId, int member) const ...@@ -597,16 +581,20 @@ Id Builder::getContainedTypeId(Id typeId, int member) const
} }
// Return the immediately contained type of a given composite type. // Return the immediately contained type of a given composite type.
Id Builder::getContainedTypeId(Id typeId) const { return getContainedTypeId(typeId, 0); } Id Builder::getContainedTypeId(Id typeId) const
{
return getContainedTypeId(typeId, 0);
}
// See if a scalar constant of this type has already been created, so it // See if a scalar constant of this type has already been created, so it
// can be reused rather than duplicated. (Required by the specification). // can be reused rather than duplicated. (Required by the specification).
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) const Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) const
{ {
Instruction* constant; Instruction* constant;
for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
{
constant = groupedConstants[typeClass][i]; constant = groupedConstants[typeClass][i];
if (constant->getOpCode() == opcode && constant->getTypeId() == typeId && if (constant->getOpCode() == opcode &&
constant->getTypeId() == typeId &&
constant->getImmediateOperand(0) == value) constant->getImmediateOperand(0) == value)
return constant->getResultId(); return constant->getResultId();
} }
...@@ -618,11 +606,12 @@ Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned valu ...@@ -618,11 +606,12 @@ Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned valu
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const
{ {
Instruction* constant; Instruction* constant;
for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
{
constant = groupedConstants[typeClass][i]; constant = groupedConstants[typeClass][i];
if (constant->getOpCode() == opcode && constant->getTypeId() == typeId && if (constant->getOpCode() == opcode &&
constant->getImmediateOperand(0) == v1 && constant->getImmediateOperand(1) == v2) constant->getTypeId() == typeId &&
constant->getImmediateOperand(0) == v1 &&
constant->getImmediateOperand(1) == v2)
return constant->getResultId(); return constant->getResultId();
} }
...@@ -634,9 +623,8 @@ Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, ...@@ -634,9 +623,8 @@ Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1,
// the value consumed will be a constant, so includes specialization. // the value consumed will be a constant, so includes specialization.
bool Builder::isConstantOpCode(Op opcode) const bool Builder::isConstantOpCode(Op opcode) const
{ {
switch (opcode) switch (opcode) {
{ case OpUndef:
case OpUndef:
case OpConstantTrue: case OpConstantTrue:
case OpConstantFalse: case OpConstantFalse:
case OpConstant: case OpConstant:
...@@ -673,16 +661,13 @@ Id Builder::makeBoolConstant(bool b, bool specConstant) ...@@ -673,16 +661,13 @@ Id Builder::makeBoolConstant(bool b, bool specConstant)
{ {
Id typeId = makeBoolType(); Id typeId = makeBoolType();
Instruction* constant; Instruction* constant;
Op opcode = specConstant ? (b ? OpSpecConstantTrue : OpSpecConstantFalse) Op opcode = specConstant ? (b ? OpSpecConstantTrue : OpSpecConstantFalse) : (b ? OpConstantTrue : OpConstantFalse);
: (b ? OpConstantTrue : OpConstantFalse);
// See if we already made it. Applies only to regular constants, because specialization constants // See if we already made it. Applies only to regular constants, because specialization constants
// must remain distinct for the purpose of applying a SpecId decoration. // must remain distinct for the purpose of applying a SpecId decoration.
if (!specConstant) if (! specConstant) {
{
Id existing = 0; Id existing = 0;
for (int i = 0; i < (int)groupedConstants[OpTypeBool].size(); ++i) for (int i = 0; i < (int)groupedConstants[OpTypeBool].size(); ++i) {
{
constant = groupedConstants[OpTypeBool][i]; constant = groupedConstants[OpTypeBool][i];
if (constant->getTypeId() == typeId && constant->getOpCode() == opcode) if (constant->getTypeId() == typeId && constant->getOpCode() == opcode)
existing = constant->getResultId(); existing = constant->getResultId();
...@@ -707,8 +692,7 @@ Id Builder::makeIntConstant(Id typeId, unsigned value, bool specConstant) ...@@ -707,8 +692,7 @@ Id Builder::makeIntConstant(Id typeId, unsigned value, bool specConstant)
// See if we already made it. Applies only to regular constants, because specialization constants // See if we already made it. Applies only to regular constants, because specialization constants
// must remain distinct for the purpose of applying a SpecId decoration. // must remain distinct for the purpose of applying a SpecId decoration.
if (!specConstant) if (! specConstant) {
{
Id existing = findScalarConstant(OpTypeInt, opcode, typeId, value); Id existing = findScalarConstant(OpTypeInt, opcode, typeId, value);
if (existing) if (existing)
return existing; return existing;
...@@ -752,17 +736,13 @@ Id Builder::makeFloatConstant(float f, bool specConstant) ...@@ -752,17 +736,13 @@ Id Builder::makeFloatConstant(float f, bool specConstant)
{ {
Op opcode = specConstant ? OpSpecConstant : OpConstant; Op opcode = specConstant ? OpSpecConstant : OpConstant;
Id typeId = makeFloatType(32); Id typeId = makeFloatType(32);
union { union { float fl; unsigned int ui; } u;
float fl;
unsigned int ui;
} u;
u.fl = f; u.fl = f;
unsigned value = u.ui; unsigned value = u.ui;
// See if we already made it. Applies only to regular constants, because specialization constants // See if we already made it. Applies only to regular constants, because specialization constants
// must remain distinct for the purpose of applying a SpecId decoration. // must remain distinct for the purpose of applying a SpecId decoration.
if (!specConstant) if (! specConstant) {
{
Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, value); Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, value);
if (existing) if (existing)
return existing; return existing;
...@@ -781,10 +761,7 @@ Id Builder::makeDoubleConstant(double d, bool specConstant) ...@@ -781,10 +761,7 @@ Id Builder::makeDoubleConstant(double d, bool specConstant)
{ {
Op opcode = specConstant ? OpSpecConstant : OpConstant; Op opcode = specConstant ? OpSpecConstant : OpConstant;
Id typeId = makeFloatType(64); Id typeId = makeFloatType(64);
union { union { double db; unsigned long long ull; } u;
double db;
unsigned long long ull;
} u;
u.db = d; u.db = d;
unsigned long long value = u.ull; unsigned long long value = u.ull;
unsigned op1 = value & 0xFFFFFFFF; unsigned op1 = value & 0xFFFFFFFF;
...@@ -792,8 +769,7 @@ Id Builder::makeDoubleConstant(double d, bool specConstant) ...@@ -792,8 +769,7 @@ Id Builder::makeDoubleConstant(double d, bool specConstant)
// See if we already made it. Applies only to regular constants, because specialization constants // See if we already made it. Applies only to regular constants, because specialization constants
// must remain distinct for the purpose of applying a SpecId decoration. // must remain distinct for the purpose of applying a SpecId decoration.
if (!specConstant) if (! specConstant) {
{
Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, op1, op2); Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, op1, op2);
if (existing) if (existing)
return existing; return existing;
...@@ -813,8 +789,7 @@ Id Builder::findCompositeConstant(Op typeClass, std::vector<Id>& comps) const ...@@ -813,8 +789,7 @@ Id Builder::findCompositeConstant(Op typeClass, std::vector<Id>& comps) const
{ {
Instruction* constant = 0; Instruction* constant = 0;
bool found = false; bool found = false;
for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
{
constant = groupedConstants[typeClass][i]; constant = groupedConstants[typeClass][i];
// same shape? // same shape?
...@@ -823,16 +798,13 @@ Id Builder::findCompositeConstant(Op typeClass, std::vector<Id>& comps) const ...@@ -823,16 +798,13 @@ Id Builder::findCompositeConstant(Op typeClass, std::vector<Id>& comps) const
// same contents? // same contents?
bool mismatch = false; bool mismatch = false;
for (int op = 0; op < constant->getNumOperands(); ++op) for (int op = 0; op < constant->getNumOperands(); ++op) {
{ if (constant->getIdOperand(op) != comps[op]) {
if (constant->getIdOperand(op) != comps[op])
{
mismatch = true; mismatch = true;
break; break;
} }
} }
if (!mismatch) if (! mismatch) {
{
found = true; found = true;
break; break;
} }
...@@ -848,8 +820,7 @@ Id Builder::makeCompositeConstant(Id typeId, std::vector<Id>& members, bool spec ...@@ -848,8 +820,7 @@ Id Builder::makeCompositeConstant(Id typeId, std::vector<Id>& members, bool spec
assert(typeId); assert(typeId);
Op typeClass = getTypeClass(typeId); Op typeClass = getTypeClass(typeId);
switch (typeClass) switch (typeClass) {
{
case OpTypeVector: case OpTypeVector:
case OpTypeArray: case OpTypeArray:
case OpTypeStruct: case OpTypeStruct:
...@@ -860,8 +831,7 @@ Id Builder::makeCompositeConstant(Id typeId, std::vector<Id>& members, bool spec ...@@ -860,8 +831,7 @@ Id Builder::makeCompositeConstant(Id typeId, std::vector<Id>& members, bool spec
return makeFloatConstant(0.0); return makeFloatConstant(0.0);
} }
if (!specConstant) if (! specConstant) {
{
Id existing = findCompositeConstant(typeClass, members); Id existing = findCompositeConstant(typeClass, members);
if (existing) if (existing)
return existing; return existing;
...@@ -890,8 +860,7 @@ Instruction* Builder::addEntryPoint(ExecutionModel model, Function* function, co ...@@ -890,8 +860,7 @@ Instruction* Builder::addEntryPoint(ExecutionModel model, Function* function, co
} }
// Currently relying on the fact that all 'value' of interest are small non-negative values. // Currently relying on the fact that all 'value' of interest are small non-negative values.
void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, int value1, int value2, void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, int value1, int value2, int value3)
int value3)
{ {
Instruction* instr = new Instruction(OpExecutionMode); Instruction* instr = new Instruction(OpExecutionMode);
instr->addIdOperand(entryPoint->getId()); instr->addIdOperand(entryPoint->getId());
...@@ -964,7 +933,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat ...@@ -964,7 +933,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
// Comments in header // Comments in header
Function* Builder::makeEntrypoint(const char* entryPoint) Function* Builder::makeEntrypoint(const char* entryPoint)
{ {
assert(!mainFunction); assert(! mainFunction);
Block* entry; Block* entry;
std::vector<Id> params; std::vector<Id> params;
...@@ -977,8 +946,7 @@ Function* Builder::makeEntrypoint(const char* entryPoint) ...@@ -977,8 +946,7 @@ Function* Builder::makeEntrypoint(const char* entryPoint)
// Comments in header // Comments in header
Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name, Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name,
const std::vector<Id>& paramTypes, const std::vector<Id>& paramTypes, const std::vector<Decoration>& precisions, Block **entry)
const std::vector<Decoration>& precisions, Block** entry)
{ {
// Make the function and initial instructions in it // Make the function and initial instructions in it
Id typeId = makeFunctionType(returnType, paramTypes); Id typeId = makeFunctionType(returnType, paramTypes);
...@@ -991,8 +959,7 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const ...@@ -991,8 +959,7 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
setPrecision(firstParamId + p, precisions[p]); setPrecision(firstParamId + p, precisions[p]);
// CFG // CFG
if (entry) if (entry) {
{
*entry = new Block(getUniqueId(), *function); *entry = new Block(getUniqueId(), *function);
function->addBlock(*entry); function->addBlock(*entry);
setBuildPoint(*entry); setBuildPoint(*entry);
...@@ -1009,16 +976,14 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const ...@@ -1009,16 +976,14 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
// Comments in header // Comments in header
void Builder::makeReturn(bool implicit, Id retVal) void Builder::makeReturn(bool implicit, Id retVal)
{ {
if (retVal) if (retVal) {
{
Instruction* inst = new Instruction(NoResult, NoType, OpReturnValue); Instruction* inst = new Instruction(NoResult, NoType, OpReturnValue);
inst->addIdOperand(retVal); inst->addIdOperand(retVal);
buildPoint->addInstruction(std::unique_ptr<Instruction>(inst)); buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
} else } else
buildPoint->addInstruction( buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(NoResult, NoType, OpReturn)));
std::unique_ptr<Instruction>(new Instruction(NoResult, NoType, OpReturn)));
if (!implicit) if (! implicit)
createAndSetNoPredecessorBlock("post-return"); createAndSetNoPredecessorBlock("post-return");
} }
...@@ -1030,12 +995,10 @@ void Builder::leaveFunction() ...@@ -1030,12 +995,10 @@ void Builder::leaveFunction()
assert(block); assert(block);
// If our function did not contain a return, add a return void now. // If our function did not contain a return, add a return void now.
if (!block->isTerminated()) if (! block->isTerminated()) {
{
if (function.getReturnType() == makeVoidType()) if (function.getReturnType() == makeVoidType())
makeReturn(true); makeReturn(true);
else else {
{
makeReturn(true, createUndefined(function.getReturnType())); makeReturn(true, createUndefined(function.getReturnType()));
} }
} }
...@@ -1055,8 +1018,7 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name) ...@@ -1055,8 +1018,7 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name)
Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable); Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable);
inst->addImmediateOperand(storageClass); inst->addImmediateOperand(storageClass);
switch (storageClass) switch (storageClass) {
{
case StorageClassFunction: case StorageClassFunction:
// Validation rules require the declaration in the entry block // Validation rules require the declaration in the entry block
buildPoint->getParent().addLocalVariable(std::unique_ptr<Instruction>(inst)); buildPoint->getParent().addLocalVariable(std::unique_ptr<Instruction>(inst));
...@@ -1077,9 +1039,9 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name) ...@@ -1077,9 +1039,9 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name)
// Comments in header // Comments in header
Id Builder::createUndefined(Id type) Id Builder::createUndefined(Id type)
{ {
Instruction* inst = new Instruction(getUniqueId(), type, OpUndef); Instruction* inst = new Instruction(getUniqueId(), type, OpUndef);
buildPoint->addInstruction(std::unique_ptr<Instruction>(inst)); buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
return inst->getResultId(); return inst->getResultId();
} }
// Comments in header // Comments in header
...@@ -1108,10 +1070,8 @@ Id Builder::createAccessChain(StorageClass storageClass, Id base, std::vector<Id ...@@ -1108,10 +1070,8 @@ Id Builder::createAccessChain(StorageClass storageClass, Id base, std::vector<Id
spv::Id typeId = getTypeId(base); spv::Id typeId = getTypeId(base);
assert(isPointerType(typeId) && offsets.size() > 0); assert(isPointerType(typeId) && offsets.size() > 0);
typeId = getContainedTypeId(typeId); typeId = getContainedTypeId(typeId);
for (int i = 0; i < (int)offsets.size(); ++i) for (int i = 0; i < (int)offsets.size(); ++i) {
{ if (isStructType(typeId)) {
if (isStructType(typeId))
{
assert(isConstantScalar(offsets[i])); assert(isConstantScalar(offsets[i]));
typeId = getContainedTypeId(typeId, getConstantScalar(offsets[i])); typeId = getContainedTypeId(typeId, getConstantScalar(offsets[i]));
} else } else
...@@ -1181,8 +1141,7 @@ Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, unsigned i ...@@ -1181,8 +1141,7 @@ Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, unsigned i
return insert->getResultId(); return insert->getResultId();
} }
Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, std::vector<unsigned>& indexes)
std::vector<unsigned>& indexes)
{ {
Instruction* insert = new Instruction(getUniqueId(), typeId, OpCompositeInsert); Instruction* insert = new Instruction(getUniqueId(), typeId, OpCompositeInsert);
insert->addIdOperand(object); insert->addIdOperand(object);
...@@ -1345,8 +1304,7 @@ Id Builder::createFunctionCall(spv::Function* function, std::vector<spv::Id>& ar ...@@ -1345,8 +1304,7 @@ Id Builder::createFunctionCall(spv::Function* function, std::vector<spv::Id>& ar
} }
// Comments in header // Comments in header
Id Builder::createRvalueSwizzle(Decoration precision, Id typeId, Id source, Id Builder::createRvalueSwizzle(Decoration precision, Id typeId, Id source, std::vector<unsigned>& channels)
std::vector<unsigned>& channels)
{ {
if (channels.size() == 1) if (channels.size() == 1)
return setPrecision(createCompositeExtract(source, typeId, channels.front()), precision); return setPrecision(createCompositeExtract(source, typeId, channels.front()), precision);
...@@ -1404,11 +1362,9 @@ void Builder::promoteScalar(Decoration precision, Id& left, Id& right) ...@@ -1404,11 +1362,9 @@ void Builder::promoteScalar(Decoration precision, Id& left, Id& right)
int direction = getNumComponents(right) - getNumComponents(left); int direction = getNumComponents(right) - getNumComponents(left);
if (direction > 0) if (direction > 0)
left = left = smearScalar(precision, left, makeVectorType(getTypeId(left), getNumComponents(right)));
smearScalar(precision, left, makeVectorType(getTypeId(left), getNumComponents(right)));
else if (direction < 0) else if (direction < 0)
right = right = smearScalar(precision, right, makeVectorType(getTypeId(right), getNumComponents(left)));
smearScalar(precision, right, makeVectorType(getTypeId(right), getNumComponents(left)));
return; return;
} }
...@@ -1462,9 +1418,7 @@ Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, std::v ...@@ -1462,9 +1418,7 @@ Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, std::v
// Accept all parameters needed to create a texture instruction. // Accept all parameters needed to create a texture instruction.
// Create the correct instruction based on the inputs, and make the call. // Create the correct instruction based on the inputs, and make the call.
Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, bool noImplicitLod, const TextureParameters& parameters)
bool proj, bool gather, bool noImplicitLod,
const TextureParameters& parameters)
{ {
static const int maxTextureArgs = 10; static const int maxTextureArgs = 10;
Id texArgs[maxTextureArgs] = {}; Id texArgs[maxTextureArgs] = {};
...@@ -1484,36 +1438,30 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, ...@@ -1484,36 +1438,30 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
// //
// Set up the optional arguments // Set up the optional arguments
// //
int optArgNum = int optArgNum = numArgs; // track which operand, if it exists, is the mask of optional arguments
numArgs; // track which operand, if it exists, is the mask of optional arguments ++numArgs; // speculatively make room for the mask operand
++numArgs; // speculatively make room for the mask operand ImageOperandsMask mask = ImageOperandsMaskNone; // the mask operand
ImageOperandsMask mask = ImageOperandsMaskNone; // the mask operand if (parameters.bias) {
if (parameters.bias)
{
mask = (ImageOperandsMask)(mask | ImageOperandsBiasMask); mask = (ImageOperandsMask)(mask | ImageOperandsBiasMask);
texArgs[numArgs++] = parameters.bias; texArgs[numArgs++] = parameters.bias;
} }
if (parameters.lod) if (parameters.lod) {
{
mask = (ImageOperandsMask)(mask | ImageOperandsLodMask); mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
texArgs[numArgs++] = parameters.lod; texArgs[numArgs++] = parameters.lod;
explicitLod = true; explicitLod = true;
} else if (parameters.gradX) } else if (parameters.gradX) {
{
mask = (ImageOperandsMask)(mask | ImageOperandsGradMask); mask = (ImageOperandsMask)(mask | ImageOperandsGradMask);
texArgs[numArgs++] = parameters.gradX; texArgs[numArgs++] = parameters.gradX;
texArgs[numArgs++] = parameters.gradY; texArgs[numArgs++] = parameters.gradY;
explicitLod = true; explicitLod = true;
} else if (noImplicitLod && !fetch && !gather) } else if (noImplicitLod && ! fetch && ! gather) {
{
// have to explicitly use lod of 0 if not allowed to have them be implicit, and // have to explicitly use lod of 0 if not allowed to have them be implicit, and
// we would otherwise be about to issue an implicit instruction // we would otherwise be about to issue an implicit instruction
mask = (ImageOperandsMask)(mask | ImageOperandsLodMask); mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
texArgs[numArgs++] = makeFloatConstant(0.0); texArgs[numArgs++] = makeFloatConstant(0.0);
explicitLod = true; explicitLod = true;
} }
if (parameters.offset) if (parameters.offset) {
{
if (isConstant(parameters.offset)) if (isConstant(parameters.offset))
mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetMask); mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetMask);
else { else {
...@@ -1522,18 +1470,15 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, ...@@ -1522,18 +1470,15 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
} }
texArgs[numArgs++] = parameters.offset; texArgs[numArgs++] = parameters.offset;
} }
if (parameters.offsets) if (parameters.offsets) {
{
mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask); mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask);
texArgs[numArgs++] = parameters.offsets; texArgs[numArgs++] = parameters.offsets;
} }
if (parameters.sample) if (parameters.sample) {
{
mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask); mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
texArgs[numArgs++] = parameters.sample; texArgs[numArgs++] = parameters.sample;
} }
if (parameters.lodClamp) if (parameters.lodClamp) {
{
// capability if this bit is used // capability if this bit is used
addCapability(CapabilityMinLod); addCapability(CapabilityMinLod);
...@@ -1549,72 +1494,69 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, ...@@ -1549,72 +1494,69 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
// Set up the instruction // Set up the instruction
// //
Op opCode = OpNop; // All paths below need to set this Op opCode = OpNop; // All paths below need to set this
if (fetch) if (fetch) {
{
if (sparse) if (sparse)
opCode = OpImageSparseFetch; opCode = OpImageSparseFetch;
else else
opCode = OpImageFetch; opCode = OpImageFetch;
} else if (gather) } else if (gather) {
{
if (parameters.Dref) if (parameters.Dref)
if (sparse) if (sparse)
opCode = OpImageSparseDrefGather; opCode = OpImageSparseDrefGather;
else else
opCode = OpImageDrefGather; opCode = OpImageDrefGather;
else if (sparse)
opCode = OpImageSparseGather;
else else
opCode = OpImageGather; if (sparse)
} else if (explicitLod) opCode = OpImageSparseGather;
{ else
if (parameters.Dref) opCode = OpImageGather;
{ } else if (explicitLod) {
if (parameters.Dref) {
if (proj) if (proj)
if (sparse) if (sparse)
opCode = OpImageSparseSampleProjDrefExplicitLod; opCode = OpImageSparseSampleProjDrefExplicitLod;
else else
opCode = OpImageSampleProjDrefExplicitLod; opCode = OpImageSampleProjDrefExplicitLod;
else if (sparse)
opCode = OpImageSparseSampleDrefExplicitLod;
else else
opCode = OpImageSampleDrefExplicitLod; if (sparse)
} else opCode = OpImageSparseSampleDrefExplicitLod;
{ else
opCode = OpImageSampleDrefExplicitLod;
} else {
if (proj) if (proj)
if (sparse) if (sparse)
opCode = OpImageSparseSampleProjExplicitLod; opCode = OpImageSparseSampleProjExplicitLod;
else else
opCode = OpImageSampleProjExplicitLod; opCode = OpImageSampleProjExplicitLod;
else if (sparse)
opCode = OpImageSparseSampleExplicitLod;
else else
opCode = OpImageSampleExplicitLod; if (sparse)
opCode = OpImageSparseSampleExplicitLod;
else
opCode = OpImageSampleExplicitLod;
} }
} else } else {
{ if (parameters.Dref) {
if (parameters.Dref)
{
if (proj) if (proj)
if (sparse) if (sparse)
opCode = OpImageSparseSampleProjDrefImplicitLod; opCode = OpImageSparseSampleProjDrefImplicitLod;
else else
opCode = OpImageSampleProjDrefImplicitLod; opCode = OpImageSampleProjDrefImplicitLod;
else if (sparse)
opCode = OpImageSparseSampleDrefImplicitLod;
else else
opCode = OpImageSampleDrefImplicitLod; if (sparse)
} else opCode = OpImageSparseSampleDrefImplicitLod;
{ else
opCode = OpImageSampleDrefImplicitLod;
} else {
if (proj) if (proj)
if (sparse) if (sparse)
opCode = OpImageSparseSampleProjImplicitLod; opCode = OpImageSparseSampleProjImplicitLod;
else else
opCode = OpImageSampleProjImplicitLod; opCode = OpImageSampleProjImplicitLod;
else if (sparse)
opCode = OpImageSparseSampleImplicitLod;
else else
opCode = OpImageSampleImplicitLod; if (sparse)
opCode = OpImageSparseSampleImplicitLod;
else
opCode = OpImageSampleImplicitLod;
} }
} }
...@@ -1622,10 +1564,8 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, ...@@ -1622,10 +1564,8 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
// This happens when a legacy shadow*() call is made, which // This happens when a legacy shadow*() call is made, which
// gets a vec4 back instead of a float. // gets a vec4 back instead of a float.
Id smearedType = resultType; Id smearedType = resultType;
if (!isScalarType(resultType)) if (! isScalarType(resultType)) {
{ switch (opCode) {
switch (opCode)
{
case OpImageSampleDrefImplicitLod: case OpImageSampleDrefImplicitLod:
case OpImageSampleDrefExplicitLod: case OpImageSampleDrefExplicitLod:
case OpImageSampleProjDrefImplicitLod: case OpImageSampleProjDrefImplicitLod:
...@@ -1640,8 +1580,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, ...@@ -1640,8 +1580,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
Id typeId0 = 0; Id typeId0 = 0;
Id typeId1 = 0; Id typeId1 = 0;
if (sparse) if (sparse) {
{
typeId0 = resultType; typeId0 = resultType;
typeId1 = getDerefTypeId(parameters.texelOut); typeId1 = getDerefTypeId(parameters.texelOut);
resultType = makeStructResultType(typeId0, typeId1); resultType = makeStructResultType(typeId0, typeId1);
...@@ -1660,8 +1599,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, ...@@ -1660,8 +1599,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
Id resultId = textureInst->getResultId(); Id resultId = textureInst->getResultId();
if (sparse) if (sparse) {
{
// set capability // set capability
addCapability(CapabilitySparseResidency); addCapability(CapabilitySparseResidency);
...@@ -1669,8 +1607,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, ...@@ -1669,8 +1607,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
createStore(createCompositeExtract(resultId, typeId1, 1), parameters.texelOut); createStore(createCompositeExtract(resultId, typeId1, 1), parameters.texelOut);
resultId = createCompositeExtract(resultId, typeId0, 0); resultId = createCompositeExtract(resultId, typeId0, 0);
setPrecision(resultId, precision); setPrecision(resultId, precision);
} else } else {
{
// When a smear is needed, do it, as per what was computed // When a smear is needed, do it, as per what was computed
// above when resultType was changed to a scalar type. // above when resultType was changed to a scalar type.
if (resultType != smearedType) if (resultType != smearedType)
...@@ -1688,14 +1625,12 @@ Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameter ...@@ -1688,14 +1625,12 @@ Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameter
// Figure out the result type // Figure out the result type
Id resultType = 0; Id resultType = 0;
switch (opCode) switch (opCode) {
{
case OpImageQuerySize: case OpImageQuerySize:
case OpImageQuerySizeLod: case OpImageQuerySizeLod:
{ {
int numComponents = 0; int numComponents = 0;
switch (getTypeDimensionality(getImageType(parameters.sampler))) switch (getTypeDimensionality(getImageType(parameters.sampler))) {
{
case Dim1D: case Dim1D:
case DimBuffer: case DimBuffer:
numComponents = 1; numComponents = 1;
...@@ -1759,14 +1694,12 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b ...@@ -1759,14 +1694,12 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
// Scalars and Vectors // Scalars and Vectors
if (isScalarType(valueType) || isVectorType(valueType)) if (isScalarType(valueType) || isVectorType(valueType)) {
{
assert(valueType == getTypeId(value2)); assert(valueType == getTypeId(value2));
// These just need a single comparison, just have // These just need a single comparison, just have
// to figure out what it is. // to figure out what it is.
Op op; Op op;
switch (getMostBasicTypeClass(valueType)) switch (getMostBasicTypeClass(valueType)) {
{
case OpTypeFloat: case OpTypeFloat:
op = equal ? OpFOrdEqual : OpFOrdNotEqual; op = equal ? OpFOrdEqual : OpFOrdNotEqual;
break; break;
...@@ -1780,12 +1713,10 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b ...@@ -1780,12 +1713,10 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
break; break;
} }
if (isScalarType(valueType)) if (isScalarType(valueType)) {
{
// scalar // scalar
resultId = createBinOp(op, boolType, value1, value2); resultId = createBinOp(op, boolType, value1, value2);
} else } else {
{
// vector // vector
resultId = createBinOp(op, makeVectorType(boolType, numConstituents), value1, value2); resultId = createBinOp(op, makeVectorType(boolType, numConstituents), value1, value2);
setPrecision(resultId, precision); setPrecision(resultId, precision);
...@@ -1801,8 +1732,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b ...@@ -1801,8 +1732,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
assert(isAggregateType(valueType) || isMatrixType(valueType)); assert(isAggregateType(valueType) || isMatrixType(valueType));
// Compare each pair of constituents // Compare each pair of constituents
for (int constituent = 0; constituent < numConstituents; ++constituent) for (int constituent = 0; constituent < numConstituents; ++constituent) {
{
std::vector<unsigned> indexes(1, constituent); std::vector<unsigned> indexes(1, constituent);
Id constituentType1 = getContainedTypeId(getTypeId(value1), constituent); Id constituentType1 = getContainedTypeId(getTypeId(value1), constituent);
Id constituentType2 = getContainedTypeId(getTypeId(value2), constituent); Id constituentType2 = getContainedTypeId(getTypeId(value2), constituent);
...@@ -1814,9 +1744,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b ...@@ -1814,9 +1744,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
if (constituent == 0) if (constituent == 0)
resultId = subResultId; resultId = subResultId;
else else
resultId = setPrecision( resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId), precision);
createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId),
precision);
} }
return resultId; return resultId;
...@@ -1825,8 +1753,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b ...@@ -1825,8 +1753,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
// OpCompositeConstruct // OpCompositeConstruct
Id Builder::createCompositeConstruct(Id typeId, std::vector<Id>& constituents) Id Builder::createCompositeConstruct(Id typeId, std::vector<Id>& constituents)
{ {
assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 && assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 && getNumTypeConstituents(typeId) == (int)constituents.size()));
getNumTypeConstituents(typeId) == (int)constituents.size()));
if (generatingOpCodeForSpecConst) { if (generatingOpCodeForSpecConst) {
// Sometime, even in spec-constant-op mode, the constant composite to be // Sometime, even in spec-constant-op mode, the constant composite to be
...@@ -1864,19 +1791,16 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc ...@@ -1864,19 +1791,16 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc
Id scalarTypeId = getScalarTypeId(resultTypeId); Id scalarTypeId = getScalarTypeId(resultTypeId);
std::vector<Id> constituents; // accumulate the arguments for OpCompositeConstruct std::vector<Id> constituents; // accumulate the arguments for OpCompositeConstruct
for (unsigned int i = 0; i < sources.size(); ++i) for (unsigned int i = 0; i < sources.size(); ++i) {
{ assert(! isAggregate(sources[i]));
assert(!isAggregate(sources[i]));
unsigned int sourceSize = getNumComponents(sources[i]); unsigned int sourceSize = getNumComponents(sources[i]);
unsigned int sourcesToUse = sourceSize; unsigned int sourcesToUse = sourceSize;
if (sourcesToUse + targetComponent > numTargetComponents) if (sourcesToUse + targetComponent > numTargetComponents)
sourcesToUse = numTargetComponents - targetComponent; sourcesToUse = numTargetComponents - targetComponent;
for (unsigned int s = 0; s < sourcesToUse; ++s) for (unsigned int s = 0; s < sourcesToUse; ++s) {
{
Id arg = sources[i]; Id arg = sources[i];
if (sourceSize > 1) if (sourceSize > 1) {
{
std::vector<unsigned> swiz; std::vector<unsigned> swiz;
swiz.push_back(s); swiz.push_back(s);
arg = createRvalueSwizzle(precision, scalarTypeId, arg, swiz); arg = createRvalueSwizzle(precision, scalarTypeId, arg, swiz);
...@@ -1900,8 +1824,7 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc ...@@ -1900,8 +1824,7 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc
} }
// Comments in header // Comments in header
Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>& sources, Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>& sources, Id resultTypeId)
Id resultTypeId)
{ {
Id componentTypeId = getScalarTypeId(resultTypeId); Id componentTypeId = getScalarTypeId(resultTypeId);
int numCols = getTypeNumColumns(resultTypeId); int numCols = getTypeNumColumns(resultTypeId);
...@@ -1930,49 +1853,39 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>& ...@@ -1930,49 +1853,39 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
} }
// modify components as dictated by the arguments // modify components as dictated by the arguments
if (sources.size() == 1 && isScalar(sources[0])) if (sources.size() == 1 && isScalar(sources[0])) {
{
// a single scalar; resets the diagonals // a single scalar; resets the diagonals
for (int col = 0; col < 4; ++col) for (int col = 0; col < 4; ++col)
ids[col][col] = sources[0]; ids[col][col] = sources[0];
} else if (isMatrix(sources[0])) } else if (isMatrix(sources[0])) {
{ // constructing from another matrix; copy over the parts that exist in both the argument and constructee
// constructing from another matrix; copy over the parts that exist in both the argument and
// constructee
Id matrix = sources[0]; Id matrix = sources[0];
int minCols = std::min(numCols, getNumColumns(matrix)); int minCols = std::min(numCols, getNumColumns(matrix));
int minRows = std::min(numRows, getNumRows(matrix)); int minRows = std::min(numRows, getNumRows(matrix));
for (int col = 0; col < minCols; ++col) for (int col = 0; col < minCols; ++col) {
{
std::vector<unsigned> indexes; std::vector<unsigned> indexes;
indexes.push_back(col); indexes.push_back(col);
for (int row = 0; row < minRows; ++row) for (int row = 0; row < minRows; ++row) {
{
indexes.push_back(row); indexes.push_back(row);
ids[col][row] = createCompositeExtract(matrix, componentTypeId, indexes); ids[col][row] = createCompositeExtract(matrix, componentTypeId, indexes);
indexes.pop_back(); indexes.pop_back();
setPrecision(ids[col][row], precision); setPrecision(ids[col][row], precision);
} }
} }
} else } else {
{
// fill in the matrix in column-major order with whatever argument components are available // fill in the matrix in column-major order with whatever argument components are available
int row = 0; int row = 0;
int col = 0; int col = 0;
for (int arg = 0; arg < (int)sources.size(); ++arg) for (int arg = 0; arg < (int)sources.size(); ++arg) {
{
Id argComp = sources[arg]; Id argComp = sources[arg];
for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp) for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp) {
{ if (getNumComponents(sources[arg]) > 1) {
if (getNumComponents(sources[arg]) > 1)
{
argComp = createCompositeExtract(sources[arg], componentTypeId, comp); argComp = createCompositeExtract(sources[arg], componentTypeId, comp);
setPrecision(argComp, precision); setPrecision(argComp, precision);
} }
ids[col][row++] = argComp; ids[col][row++] = argComp;
if (row == numRows) if (row == numRows) {
{
row = 0; row = 0;
col++; col++;
} }
...@@ -1980,14 +1893,14 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>& ...@@ -1980,14 +1893,14 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
} }
} }
// Step 2: Construct a matrix from that array. // Step 2: Construct a matrix from that array.
// First make the column vectors, then make the matrix. // First make the column vectors, then make the matrix.
// make the column vectors // make the column vectors
Id columnTypeId = getContainedTypeId(resultTypeId); Id columnTypeId = getContainedTypeId(resultTypeId);
std::vector<Id> matrixColumns; std::vector<Id> matrixColumns;
for (int col = 0; col < numCols; ++col) for (int col = 0; col < numCols; ++col) {
{
std::vector<Id> vectorComponents; std::vector<Id> vectorComponents;
for (int row = 0; row < numRows; ++row) for (int row = 0; row < numRows; ++row)
vectorComponents.push_back(ids[col][row]); vectorComponents.push_back(ids[col][row]);
...@@ -2001,7 +1914,10 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>& ...@@ -2001,7 +1914,10 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
} }
// Comments in header // Comments in header
Builder::If::If(Id cond, Builder& gb) : builder(gb), condition(cond), elseBlock(0) Builder::If::If(Id cond, Builder& gb) :
builder(gb),
condition(cond),
elseBlock(0)
{ {
function = &builder.getBuildPoint()->getParent(); function = &builder.getBuildPoint()->getParent();
...@@ -2053,8 +1969,7 @@ void Builder::If::makeEndIf() ...@@ -2053,8 +1969,7 @@ void Builder::If::makeEndIf()
} }
// Comments in header // Comments in header
void Builder::makeSwitch(Id selector, int numSegments, std::vector<int>& caseValues, void Builder::makeSwitch(Id selector, int numSegments, std::vector<int>& caseValues, std::vector<int>& valueIndexToSegment, int defaultSegment,
std::vector<int>& valueIndexToSegment, int defaultSegment,
std::vector<Block*>& segmentBlocks) std::vector<Block*>& segmentBlocks)
{ {
Function& function = buildPoint->getParent(); Function& function = buildPoint->getParent();
...@@ -2074,8 +1989,7 @@ void Builder::makeSwitch(Id selector, int numSegments, std::vector<int>& caseVal ...@@ -2074,8 +1989,7 @@ void Builder::makeSwitch(Id selector, int numSegments, std::vector<int>& caseVal
auto defaultOrMerge = (defaultSegment >= 0) ? segmentBlocks[defaultSegment] : mergeBlock; auto defaultOrMerge = (defaultSegment >= 0) ? segmentBlocks[defaultSegment] : mergeBlock;
switchInst->addIdOperand(defaultOrMerge->getId()); switchInst->addIdOperand(defaultOrMerge->getId());
defaultOrMerge->addPredecessor(buildPoint); defaultOrMerge->addPredecessor(buildPoint);
for (int i = 0; i < (int)caseValues.size(); ++i) for (int i = 0; i < (int)caseValues.size(); ++i) {
{
switchInst->addImmediateOperand(caseValues[i]); switchInst->addImmediateOperand(caseValues[i]);
switchInst->addIdOperand(segmentBlocks[valueIndexToSegment[i]]->getId()); switchInst->addIdOperand(segmentBlocks[valueIndexToSegment[i]]->getId());
segmentBlocks[valueIndexToSegment[i]]->addPredecessor(buildPoint); segmentBlocks[valueIndexToSegment[i]]->addPredecessor(buildPoint);
...@@ -2098,10 +2012,9 @@ void Builder::addSwitchBreak() ...@@ -2098,10 +2012,9 @@ void Builder::addSwitchBreak()
void Builder::nextSwitchSegment(std::vector<Block*>& segmentBlock, int nextSegment) void Builder::nextSwitchSegment(std::vector<Block*>& segmentBlock, int nextSegment)
{ {
int lastSegment = nextSegment - 1; int lastSegment = nextSegment - 1;
if (lastSegment >= 0) if (lastSegment >= 0) {
{
// Close out previous segment by jumping, if necessary, to next segment // Close out previous segment by jumping, if necessary, to next segment
if (!buildPoint->isTerminated()) if (! buildPoint->isTerminated())
createBranch(segmentBlock[nextSegment]); createBranch(segmentBlock[nextSegment]);
} }
Block* block = segmentBlock[nextSegment]; Block* block = segmentBlock[nextSegment];
...@@ -2113,7 +2026,7 @@ void Builder::nextSwitchSegment(std::vector<Block*>& segmentBlock, int nextSegme ...@@ -2113,7 +2026,7 @@ void Builder::nextSwitchSegment(std::vector<Block*>& segmentBlock, int nextSegme
void Builder::endSwitch(std::vector<Block*>& /*segmentBlock*/) void Builder::endSwitch(std::vector<Block*>& /*segmentBlock*/)
{ {
// Close out previous segment by jumping, if necessary, to next segment // Close out previous segment by jumping, if necessary, to next segment
if (!buildPoint->isTerminated()) if (! buildPoint->isTerminated())
addSwitchBreak(); addSwitchBreak();
switchMerges.top()->getParent().addBlock(switchMerges.top()); switchMerges.top()->getParent().addBlock(switchMerges.top());
...@@ -2152,7 +2065,11 @@ void Builder::createLoopExit() ...@@ -2152,7 +2065,11 @@ void Builder::createLoopExit()
createAndSetNoPredecessorBlock("post-loop-break"); createAndSetNoPredecessorBlock("post-loop-break");
} }
void Builder::closeLoop() { loops.pop(); } void Builder::closeLoop()
{
loops.pop();
}
void Builder::clearAccessChain() void Builder::clearAccessChain()
{ {
accessChain.base = NoResult; accessChain.base = NoResult;
...@@ -2173,12 +2090,10 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz ...@@ -2173,12 +2090,10 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz
accessChain.preSwizzleBaseType = preSwizzleBaseType; accessChain.preSwizzleBaseType = preSwizzleBaseType;
// if needed, propagate the swizzle for the current access chain // if needed, propagate the swizzle for the current access chain
if (accessChain.swizzle.size()) if (accessChain.swizzle.size()) {
{
std::vector<unsigned> oldSwizzle = accessChain.swizzle; std::vector<unsigned> oldSwizzle = accessChain.swizzle;
accessChain.swizzle.resize(0); accessChain.swizzle.resize(0);
for (unsigned int i = 0; i < swizzle.size(); ++i) for (unsigned int i = 0; i < swizzle.size(); ++i) {
{
accessChain.swizzle.push_back(oldSwizzle[swizzle[i]]); accessChain.swizzle.push_back(oldSwizzle[swizzle[i]]);
} }
} else } else
...@@ -2202,19 +2117,15 @@ void Builder::accessChainStore(Id rvalue) ...@@ -2202,19 +2117,15 @@ void Builder::accessChainStore(Id rvalue)
// If swizzle still exists, it is out-of-order or not full, we must load the target vector, // If swizzle still exists, it is out-of-order or not full, we must load the target vector,
// extract and insert elements to perform writeMask and/or swizzle. // extract and insert elements to perform writeMask and/or swizzle.
Id source = NoResult; Id source = NoResult;
if (accessChain.swizzle.size()) if (accessChain.swizzle.size()) {
{
Id tempBaseId = createLoad(base); Id tempBaseId = createLoad(base);
source = source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, rvalue, accessChain.swizzle);
createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, rvalue, accessChain.swizzle);
} }
// dynamic component selection // dynamic component selection
if (accessChain.component != NoResult) if (accessChain.component != NoResult) {
{
Id tempBaseId = (source == NoResult) ? createLoad(base) : source; Id tempBaseId = (source == NoResult) ? createLoad(base) : source;
source = createVectorInsertDynamic(tempBaseId, getTypeId(tempBaseId), rvalue, source = createVectorInsertDynamic(tempBaseId, getTypeId(tempBaseId), rvalue, accessChain.component);
accessChain.component);
} }
if (source == NoResult) if (source == NoResult)
...@@ -2228,25 +2139,19 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType) ...@@ -2228,25 +2139,19 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
{ {
Id id; Id id;
if (accessChain.isRValue) if (accessChain.isRValue) {
{
// transfer access chain, but keep it static, so we can stay in registers // transfer access chain, but keep it static, so we can stay in registers
transferAccessChainSwizzle(false); transferAccessChainSwizzle(false);
if (accessChain.indexChain.size() > 0) if (accessChain.indexChain.size() > 0) {
{ Id swizzleBase = accessChain.preSwizzleBaseType != NoType ? accessChain.preSwizzleBaseType : resultType;
Id swizzleBase = accessChain.preSwizzleBaseType != NoType
? accessChain.preSwizzleBaseType
: resultType;
// if all the accesses are constants, we can use OpCompositeExtract // if all the accesses are constants, we can use OpCompositeExtract
std::vector<unsigned> indexes; std::vector<unsigned> indexes;
bool constant = true; bool constant = true;
for (int i = 0; i < (int)accessChain.indexChain.size(); ++i) for (int i = 0; i < (int)accessChain.indexChain.size(); ++i) {
{
if (isConstantScalar(accessChain.indexChain[i])) if (isConstantScalar(accessChain.indexChain[i]))
indexes.push_back(getConstantScalar(accessChain.indexChain[i])); indexes.push_back(getConstantScalar(accessChain.indexChain[i]));
else else {
{
constant = false; constant = false;
break; break;
} }
...@@ -2254,11 +2159,9 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType) ...@@ -2254,11 +2159,9 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
if (constant) if (constant)
id = createCompositeExtract(accessChain.base, swizzleBase, indexes); id = createCompositeExtract(accessChain.base, swizzleBase, indexes);
else else {
{
// make a new function variable for this r-value // make a new function variable for this r-value
Id lValue = Id lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable");
createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable");
// store into it // store into it
createStore(accessChain.base, lValue); createStore(accessChain.base, lValue);
...@@ -2273,8 +2176,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType) ...@@ -2273,8 +2176,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
setPrecision(id, precision); setPrecision(id, precision);
} else } else
id = accessChain.base; // no precision, it was set when this was defined id = accessChain.base; // no precision, it was set when this was defined
} else } else {
{
transferAccessChainSwizzle(true); transferAccessChainSwizzle(true);
// load through the access chain // load through the access chain
id = createLoad(collapseAccessChain()); id = createLoad(collapseAccessChain());
...@@ -2287,8 +2189,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType) ...@@ -2287,8 +2189,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
// Do remaining swizzling // Do remaining swizzling
// First, static swizzling // First, static swizzling
if (accessChain.swizzle.size()) if (accessChain.swizzle.size()) {
{
// static swizzle // static swizzle
Id swizzledType = getScalarTypeId(getTypeId(id)); Id swizzledType = getScalarTypeId(getTypeId(id));
if (accessChain.swizzle.size() > 1) if (accessChain.swizzle.size() > 1)
...@@ -2298,8 +2199,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType) ...@@ -2298,8 +2199,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
// dynamic single-component selection // dynamic single-component selection
if (accessChain.component != NoResult) if (accessChain.component != NoResult)
id = setPrecision(createVectorExtractDynamic(id, resultType, accessChain.component), id = setPrecision(createVectorExtractDynamic(id, resultType, accessChain.component), precision);
precision);
return id; return id;
} }
...@@ -2329,12 +2229,11 @@ Id Builder::accessChainGetInferredType() ...@@ -2329,12 +2229,11 @@ Id Builder::accessChainGetInferredType()
Id type = getTypeId(accessChain.base); Id type = getTypeId(accessChain.base);
// do initial dereference // do initial dereference
if (!accessChain.isRValue) if (! accessChain.isRValue)
type = getContainedTypeId(type); type = getContainedTypeId(type);
// dereference each index // dereference each index
for (auto it = accessChain.indexChain.cbegin(); it != accessChain.indexChain.cend(); ++it) for (auto it = accessChain.indexChain.cbegin(); it != accessChain.indexChain.cend(); ++it) {
{
if (isStructType(type)) if (isStructType(type))
type = getContainedTypeId(type, getConstantScalar(*it)); type = getContainedTypeId(type, getConstantScalar(*it));
else else
...@@ -2355,29 +2254,26 @@ Id Builder::accessChainGetInferredType() ...@@ -2355,29 +2254,26 @@ Id Builder::accessChainGetInferredType()
} }
// comment in header // comment in header
void Builder::eliminateDeadDecorations() void Builder::eliminateDeadDecorations() {
{
std::unordered_set<const Block*> reachable_blocks; std::unordered_set<const Block*> reachable_blocks;
std::unordered_set<Id> unreachable_definitions; std::unordered_set<Id> unreachable_definitions;
// Collect IDs defined in unreachable blocks. For each function, label the // Collect IDs defined in unreachable blocks. For each function, label the
// reachable blocks first. Then for each unreachable block, collect the // reachable blocks first. Then for each unreachable block, collect the
// result IDs of the instructions in it. // result IDs of the instructions in it.
for (std::vector<Function*>::const_iterator fi = module.getFunctions().cbegin(); for (std::vector<Function*>::const_iterator fi = module.getFunctions().cbegin();
fi != module.getFunctions().cend(); fi++) fi != module.getFunctions().cend(); fi++) {
{
Function* f = *fi; Function* f = *fi;
Block* entry = f->getEntryBlock(); Block* entry = f->getEntryBlock();
inReadableOrder(entry, [&reachable_blocks](const Block* b) { reachable_blocks.insert(b); }); inReadableOrder(entry, [&reachable_blocks](const Block* b) {
reachable_blocks.insert(b);
});
for (std::vector<Block*>::const_iterator bi = f->getBlocks().cbegin(); for (std::vector<Block*>::const_iterator bi = f->getBlocks().cbegin();
bi != f->getBlocks().cend(); bi++) bi != f->getBlocks().cend(); bi++) {
{
Block* b = *bi; Block* b = *bi;
if (!reachable_blocks.count(b)) if (!reachable_blocks.count(b)) {
{ for (std::vector<std::unique_ptr<Instruction> >::const_iterator
for (std::vector<std::unique_ptr<Instruction> >::const_iterator ii = ii = b->getInstructions().cbegin();
b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ii++) {
ii != b->getInstructions().cend(); ii++)
{
Instruction* i = ii->get(); Instruction* i = ii->get();
unreachable_definitions.insert(i->getResultId()); unreachable_definitions.insert(i->getResultId());
} }
...@@ -2403,8 +2299,7 @@ void Builder::dump(std::vector<unsigned int>& out) const ...@@ -2403,8 +2299,7 @@ void Builder::dump(std::vector<unsigned int>& out) const
out.push_back(0); out.push_back(0);
// Capabilities // Capabilities
for (auto it = capabilities.cbegin(); it != capabilities.cend(); ++it) for (auto it = capabilities.cbegin(); it != capabilities.cend(); ++it) {
{
Instruction capInst(0, 0, OpCapability); Instruction capInst(0, 0, OpCapability);
capInst.addImmediateOperand(*it); capInst.addImmediateOperand(*it);
capInst.dump(out); capInst.dump(out);
...@@ -2423,15 +2318,13 @@ void Builder::dump(std::vector<unsigned int>& out) const ...@@ -2423,15 +2318,13 @@ void Builder::dump(std::vector<unsigned int>& out) const
dumpInstructions(out, executionModes); dumpInstructions(out, executionModes);
// Debug instructions // Debug instructions
if (source != SourceLanguageUnknown) if (source != SourceLanguageUnknown) {
{
Instruction sourceInst(0, 0, OpSource); Instruction sourceInst(0, 0, OpSource);
sourceInst.addImmediateOperand(source); sourceInst.addImmediateOperand(source);
sourceInst.addImmediateOperand(sourceVersion); sourceInst.addImmediateOperand(sourceVersion);
sourceInst.dump(out); sourceInst.dump(out);
} }
for (int e = 0; e < (int)extensions.size(); ++e) for (int e = 0; e < (int)extensions.size(); ++e) {
{
Instruction extInst(0, 0, OpSourceExtension); Instruction extInst(0, 0, OpSourceExtension);
extInst.addStringOperand(extensions[e]); extInst.addStringOperand(extensions[e]);
extInst.dump(out); extInst.dump(out);
...@@ -2462,14 +2355,10 @@ Id Builder::collapseAccessChain() ...@@ -2462,14 +2355,10 @@ Id Builder::collapseAccessChain()
{ {
assert(accessChain.isRValue == false); assert(accessChain.isRValue == false);
if (accessChain.indexChain.size() > 0) if (accessChain.indexChain.size() > 0) {
{ if (accessChain.instr == 0) {
if (accessChain.instr == 0) StorageClass storageClass = (StorageClass)module.getStorageClass(getTypeId(accessChain.base));
{ accessChain.instr = createAccessChain(storageClass, accessChain.base, accessChain.indexChain);
StorageClass storageClass =
(StorageClass)module.getStorageClass(getTypeId(accessChain.base));
accessChain.instr =
createAccessChain(storageClass, accessChain.base, accessChain.indexChain);
} }
return accessChain.instr; return accessChain.instr;
...@@ -2489,8 +2378,7 @@ void Builder::simplifyAccessChainSwizzle() ...@@ -2489,8 +2378,7 @@ void Builder::simplifyAccessChainSwizzle()
return; return;
// if components are out of order, it is a swizzle // if components are out of order, it is a swizzle
for (unsigned int i = 0; i < accessChain.swizzle.size(); ++i) for (unsigned int i = 0; i < accessChain.swizzle.size(); ++i) {
{
if (i != accessChain.swizzle[i]) if (i != accessChain.swizzle[i])
return; return;
} }
...@@ -2526,8 +2414,7 @@ void Builder::transferAccessChainSwizzle(bool dynamic) ...@@ -2526,8 +2414,7 @@ void Builder::transferAccessChainSwizzle(bool dynamic)
if (isBoolType(getContainedTypeId(accessChain.preSwizzleBaseType))) if (isBoolType(getContainedTypeId(accessChain.preSwizzleBaseType)))
return; return;
if (accessChain.swizzle.size() == 1) if (accessChain.swizzle.size() == 1) {
{
// handle static component // handle static component
accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle.front())); accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle.front()));
accessChain.swizzle.clear(); accessChain.swizzle.clear();
...@@ -2535,8 +2422,7 @@ void Builder::transferAccessChainSwizzle(bool dynamic) ...@@ -2535,8 +2422,7 @@ void Builder::transferAccessChainSwizzle(bool dynamic)
// component, so don't bother even looking at accessChain.component // component, so don't bother even looking at accessChain.component
accessChain.preSwizzleBaseType = NoType; accessChain.preSwizzleBaseType = NoType;
accessChain.component = NoResult; accessChain.component = NoResult;
} else if (dynamic && accessChain.component != NoResult) } else if (dynamic && accessChain.component != NoResult) {
{
// handle dynamic component // handle dynamic component
accessChain.indexChain.push_back(accessChain.component); accessChain.indexChain.push_back(accessChain.component);
accessChain.preSwizzleBaseType = NoType; accessChain.preSwizzleBaseType = NoType;
...@@ -2554,7 +2440,7 @@ void Builder::createAndSetNoPredecessorBlock(const char* /*name*/) ...@@ -2554,7 +2440,7 @@ void Builder::createAndSetNoPredecessorBlock(const char* /*name*/)
buildPoint->getParent().addBlock(block); buildPoint->getParent().addBlock(block);
setBuildPoint(block); setBuildPoint(block);
// if (name) //if (name)
// addName(block->getId(), name); // addName(block->getId(), name);
} }
...@@ -2595,11 +2481,9 @@ void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* els ...@@ -2595,11 +2481,9 @@ void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* els
elseBlock->addPredecessor(buildPoint); elseBlock->addPredecessor(buildPoint);
} }
void Builder::dumpInstructions(std::vector<unsigned int>& out, void Builder::dumpInstructions(std::vector<unsigned int>& out, const std::vector<std::unique_ptr<Instruction> >& instructions) const
const std::vector<std::unique_ptr<Instruction> >& instructions) const
{ {
for (int i = 0; i < (int)instructions.size(); ++i) for (int i = 0; i < (int)instructions.size(); ++i) {
{
instructions[i]->dump(out); instructions[i]->dump(out);
} }
} }
......
...@@ -79,8 +79,10 @@ public: ...@@ -79,8 +79,10 @@ public:
} }
void addCapability(spv::Capability cap) { capabilities.insert(cap); } void addCapability(spv::Capability cap) { capabilities.insert(cap); }
// To get a new <id> for anything needing a new one. // To get a new <id> for anything needing a new one.
Id getUniqueId() { return ++uniqueId; } Id getUniqueId() { return ++uniqueId; }
// To get a set of new <id>s, e.g., for a set of function parameters // To get a set of new <id>s, e.g., for a set of function parameters
Id getUniqueIds(int numIds) Id getUniqueIds(int numIds)
{ {
...@@ -93,7 +95,7 @@ public: ...@@ -93,7 +95,7 @@ public:
Id makeVoidType(); Id makeVoidType();
Id makeBoolType(); Id makeBoolType();
Id makePointer(StorageClass, Id type); Id makePointer(StorageClass, Id type);
Id makeIntegerType(int width, bool hasSign); // generic Id makeIntegerType(int width, bool hasSign); // generic
Id makeIntType(int width) { return makeIntegerType(width, true); } Id makeIntType(int width) { return makeIntegerType(width, true); }
Id makeUintType(int width) { return makeIntegerType(width, false); } Id makeUintType(int width) { return makeIntegerType(width, false); }
Id makeFloatType(int width); Id makeFloatType(int width);
...@@ -104,8 +106,7 @@ public: ...@@ -104,8 +106,7 @@ public:
Id makeArrayType(Id element, Id sizeId, int stride); // 0 stride means no stride decoration Id makeArrayType(Id element, Id sizeId, int stride); // 0 stride means no stride decoration
Id makeRuntimeArray(Id element); Id makeRuntimeArray(Id element);
Id makeFunctionType(Id returnType, const std::vector<Id>& paramTypes); Id makeFunctionType(Id returnType, const std::vector<Id>& paramTypes);
Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format);
ImageFormat format);
Id makeSamplerType(); Id makeSamplerType();
Id makeSampledImageType(Id imageType); Id makeSampledImageType(Id imageType);
...@@ -122,36 +123,27 @@ public: ...@@ -122,36 +123,27 @@ public:
Id getContainedTypeId(Id typeId) const; Id getContainedTypeId(Id typeId) const;
Id getContainedTypeId(Id typeId, int) const; Id getContainedTypeId(Id typeId, int) const;
StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); } StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }
ImageFormat getImageTypeFormat(Id typeId) const ImageFormat getImageTypeFormat(Id typeId) const { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }
{
return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6);
}
bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); } bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); }
bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); } bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); }
bool isVector(Id resultId) const { return isVectorType(getTypeId(resultId)); } bool isVector(Id resultId) const { return isVectorType(getTypeId(resultId)); }
bool isMatrix(Id resultId) const { return isMatrixType(getTypeId(resultId)); } bool isMatrix(Id resultId) const { return isMatrixType(getTypeId(resultId)); }
bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); } bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); } bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }
bool isBoolType(Id typeId) const
{ bool isBoolType(Id typeId) const { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
return groupedTypes[OpTypeBool].size() > 0 && bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; }
typeId == groupedTypes[OpTypeBool].back()->getResultId(); bool isScalarType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt || getTypeClass(typeId) == OpTypeBool; }
} bool isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; }
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; } bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
bool isScalarType(Id typeId) const bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
{ bool isArrayType(Id typeId) const { return getTypeClass(typeId) == OpTypeArray; }
return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt || bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId); }
getTypeClass(typeId) == OpTypeBool; bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
} bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
bool isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; }
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
bool isArrayType(Id typeId) const { return getTypeClass(typeId) == OpTypeArray; }
bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId); }
bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; } bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
bool isConstantOpCode(Op opcode) const; bool isConstantOpCode(Op opcode) const;
bool isSpecConstantOpCode(Op opcode) const; bool isSpecConstantOpCode(Op opcode) const;
bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); } bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); }
...@@ -172,6 +164,7 @@ public: ...@@ -172,6 +164,7 @@ public:
return getNumTypeComponents(getContainedTypeId(typeId)); return getNumTypeComponents(getContainedTypeId(typeId));
} }
int getNumRows(Id resultId) const { return getTypeNumRows(getTypeId(resultId)); } int getNumRows(Id resultId) const { return getTypeNumRows(getTypeId(resultId)); }
Dim getTypeDimensionality(Id typeId) const Dim getTypeDimensionality(Id typeId) const
{ {
assert(isImageType(typeId)); assert(isImageType(typeId));
...@@ -203,8 +196,7 @@ public: ...@@ -203,8 +196,7 @@ public:
// Methods for adding information outside the CFG. // Methods for adding information outside the CFG.
Instruction* addEntryPoint(ExecutionModel, Function*, const char* name); Instruction* addEntryPoint(ExecutionModel, Function*, const char* name);
void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);
int value3 = -1);
void addName(Id, const char* name); void addName(Id, const char* name);
void addMemberName(Id, int member, const char* name); void addMemberName(Id, int member, const char* name);
void addLine(Id target, Id fileName, int line, int column); void addLine(Id target, Id fileName, int line, int column);
...@@ -222,9 +214,8 @@ public: ...@@ -222,9 +214,8 @@ public:
// Make a shader-style function, and create its entry block if entry is non-zero. // Make a shader-style function, and create its entry block if entry is non-zero.
// Return the function, pass back the entry. // Return the function, pass back the entry.
// The returned pointer is only valid for the lifetime of this builder. // The returned pointer is only valid for the lifetime of this builder.
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const std::vector<Id>& paramTypes,
const std::vector<Id>& paramTypes, const std::vector<Decoration>& precisions, Block **entry = 0);
const std::vector<Decoration>& precisions, Block** entry = 0);
// Create a return. An 'implicit' return is one not appearing in the source // Create a return. An 'implicit' return is one not appearing in the source
// code. In the case of an implicit return, no post-return block is inserted. // code. In the case of an implicit return, no post-return block is inserted.
...@@ -277,8 +268,7 @@ public: ...@@ -277,8 +268,7 @@ public:
// Take an rvalue (source) and a set of channels to extract from it to // Take an rvalue (source) and a set of channels to extract from it to
// make a new rvalue, which is returned. // make a new rvalue, which is returned.
Id createRvalueSwizzle(Decoration precision, Id typeId, Id source, Id createRvalueSwizzle(Decoration precision, Id typeId, Id source, std::vector<unsigned>& channels);
std::vector<unsigned>& channels);
// Take a copy of an lvalue (target) and a source of components, and set the // Take a copy of an lvalue (target) and a source of components, and set the
// source components into the lvalue where the 'channels' say to put them. // source components into the lvalue where the 'channels' say to put them.
...@@ -304,11 +294,10 @@ public: ...@@ -304,11 +294,10 @@ public:
// - promoteScalar(scalar, scalar) // do nothing // - promoteScalar(scalar, scalar) // do nothing
// Other forms are not allowed. // Other forms are not allowed.
// //
// Generally, the type of 'scalar' does not need to be the same type as the components in // Generally, the type of 'scalar' does not need to be the same type as the components in 'vector'.
// 'vector'.
// The type of the created vector is a vector of components of the same type as the scalar. // The type of the created vector is a vector of components of the same type as the scalar.
// //
// Note: One of the arguments will change, with the result coming back that way rather than // Note: One of the arguments will change, with the result coming back that way rather than
// through the return value. // through the return value.
void promoteScalar(Decoration precision, Id& left, Id& right); void promoteScalar(Decoration precision, Id& left, Id& right);
...@@ -338,8 +327,7 @@ public: ...@@ -338,8 +327,7 @@ public:
}; };
// Select the correct texture operation based on all inputs, and emit the correct instruction // Select the correct texture operation based on all inputs, and emit the correct instruction
Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, bool noImplicit, const TextureParameters&);
bool gather, bool noImplicit, const TextureParameters&);
// Emit the OpTextureQuery* instruction that was passed in. // Emit the OpTextureQuery* instruction that was passed in.
// Figure out the right return value and type, and return it. // Figure out the right return value and type, and return it.
...@@ -351,8 +339,7 @@ public: ...@@ -351,8 +339,7 @@ public:
Id createBitFieldInsertCall(Decoration precision, Id, Id, Id, Id); Id createBitFieldInsertCall(Decoration precision, Id, Id, Id, Id);
// Reduction comparison for composites: For equal and not-equal resulting in a scalar. // Reduction comparison for composites: For equal and not-equal resulting in a scalar.
Id createCompositeCompare(Decoration precision, Id, Id, Id createCompositeCompare(Decoration precision, Id, Id, bool /* true if for equal, false if for not-equal */);
bool /* true if for equal, false if for not-equal */);
// OpCompositeConstruct // OpCompositeConstruct
Id createCompositeConstruct(Id typeId, std::vector<Id>& constituents); Id createCompositeConstruct(Id typeId, std::vector<Id>& constituents);
...@@ -361,14 +348,14 @@ public: ...@@ -361,14 +348,14 @@ public:
Id createConstructor(Decoration precision, const std::vector<Id>& sources, Id resultTypeId); Id createConstructor(Decoration precision, const std::vector<Id>& sources, Id resultTypeId);
// matrix constructor // matrix constructor
Id createMatrixConstructor(Decoration precision, const std::vector<Id>& sources, Id createMatrixConstructor(Decoration precision, const std::vector<Id>& sources, Id constructee);
Id constructee);
// Helper to use for building nested control flow with if-then-else. // Helper to use for building nested control flow with if-then-else.
class If { class If {
public: public:
If(Id condition, Builder& builder); If(Id condition, Builder& builder);
~If() {} ~If() {}
void makeBeginElse(); void makeBeginElse();
void makeEndIf(); void makeEndIf();
...@@ -397,8 +384,7 @@ public: ...@@ -397,8 +384,7 @@ public:
// Returns the right set of basic blocks to start each code segment with, so that the caller's // Returns the right set of basic blocks to start each code segment with, so that the caller's
// recursion stack can hold the memory for it. // recursion stack can hold the memory for it.
// //
void makeSwitch(Id condition, int numSegments, std::vector<int>& caseValues, void makeSwitch(Id condition, int numSegments, std::vector<int>& caseValues, std::vector<int>& valueToSegment, int defaultSegment,
std::vector<int>& valueToSegment, int defaultSegment,
std::vector<Block*>& segmentBB); // return argument std::vector<Block*>& segmentBB); // return argument
// Add a branch to the innermost switch's merge block. // Add a branch to the innermost switch's merge block.
...@@ -464,16 +450,13 @@ public: ...@@ -464,16 +450,13 @@ public:
// //
struct AccessChain { struct AccessChain {
Id base; // for l-values, pointer to the base object, for r-values, the base object Id base; // for l-values, pointer to the base object, for r-values, the base object
std::vector<Id> indexChain; std::vector<Id> indexChain;
Id instr; // cache the instruction that generates this access chain Id instr; // cache the instruction that generates this access chain
std::vector<unsigned> std::vector<unsigned> swizzle; // each std::vector element selects the next GLSL component number
swizzle; // each std::vector element selects the next GLSL component number Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present
Id component; // a dynamic component index, can coexist with a swizzle, done after the Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present
// swizzle, NoResult if not present bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value
Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType
// unless a swizzle or component is present
bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value
}; };
// //
...@@ -484,6 +467,7 @@ public: ...@@ -484,6 +467,7 @@ public:
// for external save and restore // for external save and restore
AccessChain getAccessChain() { return accessChain; } AccessChain getAccessChain() { return accessChain; }
void setAccessChain(AccessChain newChain) { accessChain = newChain; } void setAccessChain(AccessChain newChain) { accessChain = newChain; }
// clear accessChain // clear accessChain
void clearAccessChain(); void clearAccessChain();
...@@ -502,7 +486,11 @@ public: ...@@ -502,7 +486,11 @@ public:
} }
// push offset onto the end of the chain // push offset onto the end of the chain
void accessChainPush(Id offset) { accessChain.indexChain.push_back(offset); } void accessChainPush(Id offset)
{
accessChain.indexChain.push_back(offset);
}
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle // push new swizzle onto the end of any existing swizzle, merging into a single swizzle
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType); void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType);
...@@ -554,8 +542,7 @@ public: ...@@ -554,8 +542,7 @@ public:
void simplifyAccessChainSwizzle(); void simplifyAccessChainSwizzle();
void createAndSetNoPredecessorBlock(const char*); void createAndSetNoPredecessorBlock(const char*);
void createSelectionMerge(Block* mergeBlock, unsigned int control); void createSelectionMerge(Block* mergeBlock, unsigned int control);
void dumpInstructions(std::vector<unsigned int>&, void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
const std::vector<std::unique_ptr<Instruction> >&) const;
SourceLanguage source; SourceLanguage source;
int sourceVersion; int sourceVersion;
...@@ -582,7 +569,7 @@ public: ...@@ -582,7 +569,7 @@ public:
std::vector<std::unique_ptr<Instruction> > externals; std::vector<std::unique_ptr<Instruction> > externals;
std::vector<std::unique_ptr<Function> > functions; std::vector<std::unique_ptr<Function> > functions;
// not output, internally used for quick & dirty canonical (unique) creation // not output, internally used for quick & dirty canonical (unique) creation
std::vector<Instruction*> groupedConstants[OpConstant]; // all types appear before OpConstant std::vector<Instruction*> groupedConstants[OpConstant]; // all types appear before OpConstant
std::vector<Instruction*> groupedTypes[OpConstant]; std::vector<Instruction*> groupedTypes[OpConstant];
...@@ -598,4 +585,4 @@ public: ...@@ -598,4 +585,4 @@ public:
}; // end spv namespace }; // end spv namespace
#endif // SpvBuilder_H #endif // SpvBuilder_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment