diff options
author | dan sinclair <dj2@everburning.com> | 2018-07-30 13:06:03 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-30 13:06:03 -0400 |
commit | ee22928bd9aeae85e4b45f735bdbbfdee93dd9fb (patch) | |
tree | a21f37478a079593d0bd8863ed534e00df962737 /source | |
parent | fc2a719cad2c5e464b5733e24c66258451db22b0 (diff) |
Move CompositePass code into methods. (#1740)
This Cl splits the CompositePass switch to have one method per case
label. This makes the code a lot simpler to follow.
Diffstat (limited to 'source')
-rw-r--r-- | source/val/validate_composites.cpp | 569 |
1 files changed, 290 insertions, 279 deletions
diff --git a/source/val/validate_composites.cpp b/source/val/validate_composites.cpp index 5b98df0d..928ddedc 100644 --- a/source/val/validate_composites.cpp +++ b/source/val/validate_composites.cpp @@ -133,343 +133,354 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _, return SPV_SUCCESS; } -} // anonymous namespace +spv_result_t ValidateVectorExtractDynamic(ValidationState_t& _, + const Instruction* inst) { + const SpvOp opcode = inst->opcode(); + const uint32_t result_type = inst->type_id(); + const SpvOp result_opcode = _.GetIdOpcode(result_type); + if (!spvOpcodeIsScalarType(result_opcode)) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected Result Type to be a scalar type"; + } -// Validates correctness of composite instructions. -spv_result_t CompositesPass(ValidationState_t& _, const Instruction* inst) { + const uint32_t vector_type = _.GetOperandTypeId(inst, 2); + const SpvOp vector_opcode = _.GetIdOpcode(vector_type); + if (vector_opcode != SpvOpTypeVector) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected Vector type to be OpTypeVector"; + } + + if (_.GetComponentType(vector_type) != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected Vector component type to be equal to Result Type"; + } + + const uint32_t index_type = _.GetOperandTypeId(inst, 3); + if (!_.IsIntScalarType(index_type)) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) << ": expected Index to be int scalar"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateVectorInsertDyanmic(ValidationState_t& _, + const Instruction* inst) { const SpvOp opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); - const uint32_t num_operands = static_cast<uint32_t>(inst->operands().size()); + const SpvOp result_opcode = _.GetIdOpcode(result_type); + if (result_opcode != SpvOpTypeVector) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected Result Type to be OpTypeVector"; + } - switch (opcode) { - case SpvOpVectorExtractDynamic: { - const SpvOp result_opcode = _.GetIdOpcode(result_type); - if (!spvOpcodeIsScalarType(result_opcode)) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected Result Type to be a scalar type"; - } + const uint32_t vector_type = _.GetOperandTypeId(inst, 2); + if (vector_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected Vector type to be equal to Result Type"; + } - const uint32_t vector_type = _.GetOperandTypeId(inst, 2); - const SpvOp vector_opcode = _.GetIdOpcode(vector_type); - if (vector_opcode != SpvOpTypeVector) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected Vector type to be OpTypeVector"; - } + const uint32_t component_type = _.GetOperandTypeId(inst, 3); + if (_.GetComponentType(result_type) != component_type) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected Component type to be equal to Result Type " + << "component type"; + } - if (_.GetComponentType(vector_type) != result_type) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected Vector component type to be equal to Result Type"; - } + const uint32_t index_type = _.GetOperandTypeId(inst, 4); + if (!_.IsIntScalarType(index_type)) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) << ": expected Index to be int scalar"; + } + return SPV_SUCCESS; +} - const uint32_t index_type = _.GetOperandTypeId(inst, 3); - if (!_.IsIntScalarType(index_type)) { +spv_result_t ValidateCompositeConstruct(ValidationState_t& _, + const Instruction* inst) { + const SpvOp opcode = inst->opcode(); + const uint32_t num_operands = static_cast<uint32_t>(inst->operands().size()); + const uint32_t result_type = inst->type_id(); + const SpvOp result_opcode = _.GetIdOpcode(result_type); + switch (result_opcode) { + case SpvOpTypeVector: { + const uint32_t num_result_components = _.GetDimension(result_type); + const uint32_t result_component_type = _.GetComponentType(result_type); + uint32_t given_component_count = 0; + + if (num_operands <= 3) { return _.diag(SPV_ERROR_INVALID_DATA) << spvOpcodeString(opcode) - << ": expected Index to be int scalar"; + << ": expected number of constituents to be at least 2"; } - break; - } + for (uint32_t operand_index = 2; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + if (operand_type == result_component_type) { + ++given_component_count; + } else { + if (_.GetIdOpcode(operand_type) != SpvOpTypeVector || + _.GetComponentType(operand_type) != result_component_type) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected Constituents to be scalars or vectors of " + << "the same type as Result Type components"; + } - case SpvOpVectorInsertDynamic: { - const SpvOp result_opcode = _.GetIdOpcode(result_type); - if (result_opcode != SpvOpTypeVector) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected Result Type to be OpTypeVector"; + given_component_count += _.GetDimension(operand_type); + } } - const uint32_t vector_type = _.GetOperandTypeId(inst, 2); - if (vector_type != result_type) { + if (num_result_components != given_component_count) { return _.diag(SPV_ERROR_INVALID_DATA) << spvOpcodeString(opcode) - << ": expected Vector type to be equal to Result Type"; + << ": expected total number of given components to be equal " + << "to the size of Result Type vector"; } - const uint32_t component_type = _.GetOperandTypeId(inst, 3); - if (_.GetComponentType(result_type) != component_type) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected Component type to be equal to Result Type " - << "component type"; + break; + } + case SpvOpTypeMatrix: { + uint32_t result_num_rows = 0; + uint32_t result_num_cols = 0; + uint32_t result_col_type = 0; + uint32_t result_component_type = 0; + if (!_.GetMatrixTypeInfo(result_type, &result_num_rows, &result_num_cols, + &result_col_type, &result_component_type)) { + assert(0); } - const uint32_t index_type = _.GetOperandTypeId(inst, 4); - if (!_.IsIntScalarType(index_type)) { + if (result_num_cols + 2 != num_operands) { return _.diag(SPV_ERROR_INVALID_DATA) << spvOpcodeString(opcode) - << ": expected Index to be int scalar"; + << ": expected total number of Constituents to be equal " + << "to the number of columns of Result Type matrix"; } - break; - } - - case SpvOpVectorShuffle: { - // Handled in validate_id.cpp. - // TODO(atgoo@github.com) Consider moving it here. - break; - } - - case SpvOpCompositeConstruct: { - const SpvOp result_opcode = _.GetIdOpcode(result_type); - switch (result_opcode) { - case SpvOpTypeVector: { - const uint32_t num_result_components = _.GetDimension(result_type); - const uint32_t result_component_type = - _.GetComponentType(result_type); - uint32_t given_component_count = 0; - - if (num_operands <= 3) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected number of constituents to be at least 2"; - } - - for (uint32_t operand_index = 2; operand_index < num_operands; - ++operand_index) { - const uint32_t operand_type = - _.GetOperandTypeId(inst, operand_index); - if (operand_type == result_component_type) { - ++given_component_count; - } else { - if (_.GetIdOpcode(operand_type) != SpvOpTypeVector || - _.GetComponentType(operand_type) != result_component_type) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected Constituents to be scalars or vectors of " - << "the same type as Result Type components"; - } - - given_component_count += _.GetDimension(operand_type); - } - } - - if (num_result_components != given_component_count) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected total number of given components to be equal " - << "to the size of Result Type vector"; - } - - break; - } - case SpvOpTypeMatrix: { - uint32_t result_num_rows = 0; - uint32_t result_num_cols = 0; - uint32_t result_col_type = 0; - uint32_t result_component_type = 0; - if (!_.GetMatrixTypeInfo(result_type, &result_num_rows, - &result_num_cols, &result_col_type, - &result_component_type)) { - assert(0); - } - - if (result_num_cols + 2 != num_operands) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected total number of Constituents to be equal " - << "to the number of columns of Result Type matrix"; - } - - for (uint32_t operand_index = 2; operand_index < num_operands; - ++operand_index) { - const uint32_t operand_type = - _.GetOperandTypeId(inst, operand_index); - if (operand_type != result_col_type) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected Constituent type to be equal to the column " - << "type Result Type matrix"; - } - } - - break; - } - case SpvOpTypeArray: { - const Instruction* const array_inst = _.FindDef(result_type); - assert(array_inst); - assert(array_inst->opcode() == SpvOpTypeArray); - - auto size = _.FindDef(array_inst->word(3)); - if (spvOpcodeIsSpecConstant(size->opcode())) { - // Cannot verify against the size of this array. - break; - } - - uint64_t array_size = 0; - if (!_.GetConstantValUint64(array_inst->word(3), &array_size)) { - assert(0 && "Array type definition is corrupt"); - } - - if (array_size + 2 != num_operands) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected total number of Constituents to be equal " - << "to the number of elements of Result Type array"; - } - - const uint32_t result_component_type = array_inst->word(2); - for (uint32_t operand_index = 2; operand_index < num_operands; - ++operand_index) { - const uint32_t operand_type = - _.GetOperandTypeId(inst, operand_index); - if (operand_type != result_component_type) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected Constituent type to be equal to the column " - << "type Result Type array"; - } - } - - break; - } - case SpvOpTypeStruct: { - const Instruction* const struct_inst = _.FindDef(result_type); - assert(struct_inst); - assert(struct_inst->opcode() == SpvOpTypeStruct); - - if (struct_inst->operands().size() + 1 != num_operands) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected total number of Constituents to be equal " - << "to the number of members of Result Type struct"; - } - - for (uint32_t operand_index = 2; operand_index < num_operands; - ++operand_index) { - const uint32_t operand_type = - _.GetOperandTypeId(inst, operand_index); - const uint32_t member_type = struct_inst->word(operand_index); - if (operand_type != member_type) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected Constituent type to be equal to the " - << "corresponding member type of Result Type struct"; - } - } - - break; - } - default: { + for (uint32_t operand_index = 2; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + if (operand_type != result_col_type) { return _.diag(SPV_ERROR_INVALID_DATA) << spvOpcodeString(opcode) - << ": expected Result Type to be a composite type"; + << ": expected Constituent type to be equal to the column " + << "type Result Type matrix"; } } break; } - - case SpvOpCompositeExtract: { - uint32_t member_type = 0; - if (spv_result_t error = - GetExtractInsertValueType(_, inst, &member_type)) { - return error; + case SpvOpTypeArray: { + const Instruction* const array_inst = _.FindDef(result_type); + assert(array_inst); + assert(array_inst->opcode() == SpvOpTypeArray); + + auto size = _.FindDef(array_inst->word(3)); + if (spvOpcodeIsSpecConstant(size->opcode())) { + // Cannot verify against the size of this array. + break; } - if (result_type != member_type) { - return _.diag(SPV_ERROR_INVALID_DATA) - << "Op" << spvOpcodeString(opcode) << " result type (Op" - << spvOpcodeString(_.GetIdOpcode(result_type)) - << ") does not match the type that results from indexing into " - "the " - "composite (Op" - << spvOpcodeString(_.GetIdOpcode(member_type)) << ")."; + uint64_t array_size = 0; + if (!_.GetConstantValUint64(array_inst->word(3), &array_size)) { + assert(0 && "Array type definition is corrupt"); } - break; - } - case SpvOpCompositeInsert: { - const uint32_t object_type = _.GetOperandTypeId(inst, 2); - const uint32_t composite_type = _.GetOperandTypeId(inst, 3); - - if (result_type != composite_type) { + if (array_size + 2 != num_operands) { return _.diag(SPV_ERROR_INVALID_DATA) - << "The Result Type must be the same as Composite type in Op" - << spvOpcodeString(opcode) << " yielding Result Id " - << result_type << "."; + << spvOpcodeString(opcode) + << ": expected total number of Constituents to be equal " + << "to the number of elements of Result Type array"; } - uint32_t member_type = 0; - if (spv_result_t error = - GetExtractInsertValueType(_, inst, &member_type)) { - return error; + const uint32_t result_component_type = array_inst->word(2); + for (uint32_t operand_index = 2; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + if (operand_type != result_component_type) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected Constituent type to be equal to the column " + << "type Result Type array"; + } } - if (object_type != member_type) { - return _.diag(SPV_ERROR_INVALID_DATA) - << "The Object type (Op" - << spvOpcodeString(_.GetIdOpcode(object_type)) << ") in Op" - << spvOpcodeString(opcode) - << " does not match the type that results from indexing into " - "the Composite (Op" - << spvOpcodeString(_.GetIdOpcode(member_type)) << ")."; - } break; } + case SpvOpTypeStruct: { + const Instruction* const struct_inst = _.FindDef(result_type); + assert(struct_inst); + assert(struct_inst->opcode() == SpvOpTypeStruct); - case SpvOpCopyObject: { - if (!spvOpcodeGeneratesType(_.GetIdOpcode(result_type))) { + if (struct_inst->operands().size() + 1 != num_operands) { return _.diag(SPV_ERROR_INVALID_DATA) << spvOpcodeString(opcode) - << ": expected Result Type to be a type"; + << ": expected total number of Constituents to be equal " + << "to the number of members of Result Type struct"; } - const uint32_t operand_type = _.GetOperandTypeId(inst, 2); - if (operand_type != result_type) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected Result Type and Operand type to be the same"; + for (uint32_t operand_index = 2; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + const uint32_t member_type = struct_inst->word(operand_index); + if (operand_type != member_type) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected Constituent type to be equal to the " + << "corresponding member type of Result Type struct"; + } } break; } + default: { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected Result Type to be a composite type"; + } + } + return SPV_SUCCESS; +} - case SpvOpTranspose: { - uint32_t result_num_rows = 0; - uint32_t result_num_cols = 0; - uint32_t result_col_type = 0; - uint32_t result_component_type = 0; - if (!_.GetMatrixTypeInfo(result_type, &result_num_rows, &result_num_cols, - &result_col_type, &result_component_type)) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected Result Type to be a matrix type"; - } +spv_result_t ValidateCompositeExtract(ValidationState_t& _, + const Instruction* inst) { + uint32_t member_type = 0; + if (spv_result_t error = GetExtractInsertValueType(_, inst, &member_type)) { + return error; + } - const uint32_t matrix_type = _.GetOperandTypeId(inst, 2); - uint32_t matrix_num_rows = 0; - uint32_t matrix_num_cols = 0; - uint32_t matrix_col_type = 0; - uint32_t matrix_component_type = 0; - if (!_.GetMatrixTypeInfo(matrix_type, &matrix_num_rows, &matrix_num_cols, - &matrix_col_type, &matrix_component_type)) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected Matrix to be of type OpTypeMatrix"; - } + const uint32_t result_type = inst->type_id(); + if (result_type != member_type) { + return _.diag(SPV_ERROR_INVALID_DATA) + << "Op" << spvOpcodeString(inst->opcode()) << " result type (Op" + << spvOpcodeString(_.GetIdOpcode(result_type)) + << ") does not match the type that results from indexing into " + "the " + "composite (Op" + << spvOpcodeString(_.GetIdOpcode(member_type)) << ")."; + } + return SPV_SUCCESS; +} - if (result_component_type != matrix_component_type) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected component types of Matrix and Result Type to be " - << "identical"; - } +spv_result_t ValidateCompositeInsert(ValidationState_t& _, + const Instruction* inst) { + const SpvOp opcode = inst->opcode(); + const uint32_t object_type = _.GetOperandTypeId(inst, 2); + const uint32_t composite_type = _.GetOperandTypeId(inst, 3); + const uint32_t result_type = inst->type_id(); + if (result_type != composite_type) { + return _.diag(SPV_ERROR_INVALID_DATA) + << "The Result Type must be the same as Composite type in Op" + << spvOpcodeString(opcode) << " yielding Result Id " << result_type + << "."; + } - if (result_num_rows != matrix_num_cols || - result_num_cols != matrix_num_rows) { - return _.diag(SPV_ERROR_INVALID_DATA) - << spvOpcodeString(opcode) - << ": expected number of columns and the column size of Matrix " - << "to be the reverse of those of Result Type"; - } + uint32_t member_type = 0; + if (spv_result_t error = GetExtractInsertValueType(_, inst, &member_type)) { + return error; + } + + if (object_type != member_type) { + return _.diag(SPV_ERROR_INVALID_DATA) + << "The Object type (Op" + << spvOpcodeString(_.GetIdOpcode(object_type)) << ") in Op" + << spvOpcodeString(opcode) + << " does not match the type that results from indexing into " + "the Composite (Op" + << spvOpcodeString(_.GetIdOpcode(member_type)) << ")."; + } + return SPV_SUCCESS; +} +spv_result_t ValidateCopyObject(ValidationState_t& _, const Instruction* inst) { + const SpvOp opcode = inst->opcode(); + const uint32_t result_type = inst->type_id(); + if (!spvOpcodeGeneratesType(_.GetIdOpcode(result_type))) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) << ": expected Result Type to be a type"; + } + + const uint32_t operand_type = _.GetOperandTypeId(inst, 2); + if (operand_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected Result Type and Operand type to be the same"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateTranspose(ValidationState_t& _, const Instruction* inst) { + const SpvOp opcode = inst->opcode(); + uint32_t result_num_rows = 0; + uint32_t result_num_cols = 0; + uint32_t result_col_type = 0; + uint32_t result_component_type = 0; + const uint32_t result_type = inst->type_id(); + if (!_.GetMatrixTypeInfo(result_type, &result_num_rows, &result_num_cols, + &result_col_type, &result_component_type)) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected Result Type to be a matrix type"; + } + + const uint32_t matrix_type = _.GetOperandTypeId(inst, 2); + uint32_t matrix_num_rows = 0; + uint32_t matrix_num_cols = 0; + uint32_t matrix_col_type = 0; + uint32_t matrix_component_type = 0; + if (!_.GetMatrixTypeInfo(matrix_type, &matrix_num_rows, &matrix_num_cols, + &matrix_col_type, &matrix_component_type)) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected Matrix to be of type OpTypeMatrix"; + } + + if (result_component_type != matrix_component_type) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected component types of Matrix and Result Type to be " + << "identical"; + } + + if (result_num_rows != matrix_num_cols || + result_num_cols != matrix_num_rows) { + return _.diag(SPV_ERROR_INVALID_DATA) + << spvOpcodeString(opcode) + << ": expected number of columns and the column size of Matrix " + << "to be the reverse of those of Result Type"; + } + return SPV_SUCCESS; +} + +} // anonymous namespace + +// Validates correctness of composite instructions. +spv_result_t CompositesPass(ValidationState_t& _, const Instruction* inst) { + switch (inst->opcode()) { + case SpvOpVectorExtractDynamic: + return ValidateVectorExtractDynamic(_, inst); + case SpvOpVectorInsertDynamic: + return ValidateVectorInsertDyanmic(_, inst); + case SpvOpVectorShuffle: { + // Handled in validate_id.cpp. + // TODO(atgoo@github.com) Consider moving it here. break; } - + case SpvOpCompositeConstruct: + return ValidateCompositeConstruct(_, inst); + case SpvOpCompositeExtract: + return ValidateCompositeExtract(_, inst); + case SpvOpCompositeInsert: + return ValidateCompositeInsert(_, inst); + case SpvOpCopyObject: + return ValidateCopyObject(_, inst); + case SpvOpTranspose: + return ValidateTranspose(_, inst); default: break; } |