From 74a731add43fc37322f776f27640f237202f0caa Mon Sep 17 00:00:00 2001 From: Umar Arshad Date: Sat, 9 Jan 2016 17:25:36 -0500 Subject: [PATCH] Remove static vector from GetModuleOrder --- source/validate.cpp | 82 +++----------- source/validate_types.cpp | 227 +++++++++++++++++++++++++------------- 2 files changed, 170 insertions(+), 139 deletions(-) diff --git a/source/validate.cpp b/source/validate.cpp index 0447f0dc1..7d6cdeb12 100644 --- a/source/validate.cpp +++ b/source/validate.cpp @@ -478,72 +478,17 @@ spv_result_t ModuleLayoutPass(ValidationState_t& _, "outside of a function"; } } - } else { - // This ensures no module instructions are called during function - // declarations - switch (opcode) { - case SpvOpCapability: - case SpvOpExtension: - case SpvOpExtInstImport: - case SpvOpMemoryModel: - case SpvOpEntryPoint: - case SpvOpExecutionMode: - case SpvOpSourceContinued: - case SpvOpSource: - case SpvOpSourceExtension: - case SpvOpString: - case SpvOpName: - case SpvOpMemberName: - case SpvOpDecorate: - case SpvOpMemberDecorate: - case SpvOpGroupDecorate: - case SpvOpGroupMemberDecorate: - case SpvOpDecorationGroup: - case SpvOpTypeVoid: - case SpvOpTypeBool: - case SpvOpTypeInt: - case SpvOpTypeFloat: - case SpvOpTypeVector: - case SpvOpTypeMatrix: - case SpvOpTypeImage: - case SpvOpTypeSampler: - case SpvOpTypeSampledImage: - case SpvOpTypeArray: - case SpvOpTypeRuntimeArray: - case SpvOpTypeStruct: - case SpvOpTypeOpaque: - case SpvOpTypePointer: - case SpvOpTypeFunction: - case SpvOpTypeEvent: - case SpvOpTypeDeviceEvent: - case SpvOpTypeReserveId: - case SpvOpTypeQueue: - case SpvOpTypePipe: - case SpvOpTypeForwardPointer: - case SpvOpConstantTrue: - case SpvOpConstantFalse: - case SpvOpConstant: - case SpvOpConstantComposite: - case SpvOpConstantSampler: - case SpvOpConstantNull: - case SpvOpSpecConstantTrue: - case SpvOpSpecConstantFalse: - case SpvOpSpecConstant: - case SpvOpSpecConstantComposite: - case SpvOpSpecConstantOp: - return _.diag(SPV_ERROR_INVALID_LAYOUT) << "Invalid Layout"; - case SpvOpVariable: { + } else if (_.getLayoutStage() == kLayoutFunctionDeclarations) { + if (_.isOpcodeInCurrentLayoutStage(opcode)) { + if (opcode == SpvOpVariable) { const uint32_t* storage_class = inst->words + inst->operands[2].offset; if (*storage_class != SpvStorageClassFunction) return _.diag(SPV_ERROR_INVALID_LAYOUT) << "All Variable instructions in a function must have a " "storage class of function[7]"; - } break; - default: - break; - } - if (_.getLayoutStage() == kLayoutFunctionDeclarations) { + } + switch (opcode) { case SpvOpFunction: if (_.in_function_body()) { @@ -576,10 +521,8 @@ spv_result_t ModuleLayoutPass(ValidationState_t& _, FunctionDecl::kFunctionDeclDefinition)); break; case SpvOpFunctionEnd: - assert(_.get_functions().get_block_count() == - 0 // NOTE: This should not happen - && - "Function contains blocks in function declaration section."); + assert(_.get_functions().get_block_count() == 0 && + "Function contains blocks in function declaration section"); if (_.in_function_body() == false) { return _.diag(SPV_ERROR_INVALID_LAYOUT) << "Function end instructions must be in a function body"; @@ -593,8 +536,17 @@ spv_result_t ModuleLayoutPass(ValidationState_t& _, << "A function must begin with a label"; break; } + } else { + return _.diag(SPV_ERROR_INVALID_LAYOUT) + << spvOpcodeString(opcode) + << " cannot appear in a function declaration"; } - // NOTE: Function definitions are handled by the CFGPass + } else { + if (_.isOpcodeInCurrentLayoutStage(opcode) == false) { + return _.diag(SPV_ERROR_INVALID_LAYOUT) + << " cannot appear in a funciton definition"; + } + // NOTE: Additional checks will be performed in the CfgPass function } } return SPV_SUCCESS; diff --git a/source/validate_types.cpp b/source/validate_types.cpp index 3a2e23f0d..afc08ba0b 100644 --- a/source/validate_types.cpp +++ b/source/validate_types.cpp @@ -38,85 +38,162 @@ using std::find; using std::string; using std::unordered_set; using std::vector; +using namespace libspirv; namespace { -const vector>& GetModuleOrder() { +bool IsInstructionInLayoutSection(ModuleLayoutSection layout, SpvOp op) { // See Section 2.4 + bool out = false; // clang-format off - static const vector> moduleOrder = { - {SpvOpCapability}, - {SpvOpExtension}, - {SpvOpExtInstImport}, - {SpvOpMemoryModel}, - {SpvOpEntryPoint}, - {SpvOpExecutionMode}, - { - // first set of debug instructions - SpvOpSourceContinued, - SpvOpSource, - SpvOpSourceExtension, - SpvOpString, - }, - { - // second set of debug instructions - SpvOpName, - SpvOpMemberName - }, - { - // annotation instructions - SpvOpDecorate, - SpvOpMemberDecorate, - SpvOpGroupDecorate, - SpvOpGroupMemberDecorate, - SpvOpDecorationGroup - }, - { - // All type and constant instructions - SpvOpTypeVoid, - SpvOpTypeBool, - SpvOpTypeInt, - SpvOpTypeFloat, - SpvOpTypeVector, - SpvOpTypeMatrix, - SpvOpTypeImage, - SpvOpTypeSampler, - SpvOpTypeSampledImage, - SpvOpTypeArray, - SpvOpTypeRuntimeArray, - SpvOpTypeStruct, - SpvOpTypeOpaque, - SpvOpTypePointer, - SpvOpTypeFunction, - SpvOpTypeEvent, - SpvOpTypeDeviceEvent, - SpvOpTypeReserveId, - SpvOpTypeQueue, - SpvOpTypePipe, - SpvOpTypeForwardPointer, - SpvOpConstantTrue, - SpvOpConstantFalse, - SpvOpConstant, - SpvOpConstantComposite, - SpvOpConstantSampler, - SpvOpConstantNull, - SpvOpSpecConstantTrue, - SpvOpSpecConstantFalse, - SpvOpSpecConstant, - SpvOpSpecConstantComposite, - SpvOpSpecConstantOp, - SpvOpVariable, - SpvOpLine - } - }; + switch (layout) { + case kLayoutCapabilities: out = op == SpvOpCapability; break; + case kLayoutExtensions: out = op == SpvOpExtension; break; + case kLayoutExtInstImport: out = op == SpvOpExtInstImport; break; + case kLayoutMemoryModel: out = op == SpvOpMemoryModel; break; + case kLayoutEntryPoint: out = op == SpvOpEntryPoint; break; + case kLayoutExecutionMode: out = op == SpvOpExecutionMode; break; + case kLayoutDebug1: + switch (op) { + case SpvOpSourceContinued: + case SpvOpSource: + case SpvOpSourceExtension: + case SpvOpString: + out = true; + break; + default: break; + } + break; + case kLayoutDebug2: + switch (op) { + case SpvOpName: + case SpvOpMemberName: + out = true; + break; + default: break; + } + break; + case kLayoutAnnotations: + switch (op) { + case SpvOpDecorate: + case SpvOpMemberDecorate: + case SpvOpGroupDecorate: + case SpvOpGroupMemberDecorate: + case SpvOpDecorationGroup: + out = true; + break; + default: break; + } + break; + case kLayoutTypes: + switch (op) { + case SpvOpTypeVoid: + case SpvOpTypeBool: + case SpvOpTypeInt: + case SpvOpTypeFloat: + case SpvOpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeImage: + case SpvOpTypeSampler: + case SpvOpTypeSampledImage: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: + case SpvOpTypeStruct: + case SpvOpTypeOpaque: + case SpvOpTypePointer: + case SpvOpTypeFunction: + case SpvOpTypeEvent: + case SpvOpTypeDeviceEvent: + case SpvOpTypeReserveId: + case SpvOpTypeQueue: + case SpvOpTypePipe: + case SpvOpTypeForwardPointer: + case SpvOpConstantTrue: + case SpvOpConstantFalse: + case SpvOpConstant: + case SpvOpConstantComposite: + case SpvOpConstantSampler: + case SpvOpConstantNull: + case SpvOpSpecConstantTrue: + case SpvOpSpecConstantFalse: + case SpvOpSpecConstant: + case SpvOpSpecConstantComposite: + case SpvOpSpecConstantOp: + case SpvOpVariable: + case SpvOpLine: + out = true; + break; + default: break; + } + break; + case kLayoutFunctionDeclarations: + case kLayoutFunctionDefinitions: + // NOTE: These instructions should NOT be in these layout sections + switch (op) { + case SpvOpCapability: + case SpvOpExtension: + case SpvOpExtInstImport: + case SpvOpMemoryModel: + case SpvOpEntryPoint: + case SpvOpExecutionMode: + case SpvOpSourceContinued: + case SpvOpSource: + case SpvOpSourceExtension: + case SpvOpString: + case SpvOpName: + case SpvOpMemberName: + case SpvOpDecorate: + case SpvOpMemberDecorate: + case SpvOpGroupDecorate: + case SpvOpGroupMemberDecorate: + case SpvOpDecorationGroup: + case SpvOpTypeVoid: + case SpvOpTypeBool: + case SpvOpTypeInt: + case SpvOpTypeFloat: + case SpvOpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeImage: + case SpvOpTypeSampler: + case SpvOpTypeSampledImage: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: + case SpvOpTypeStruct: + case SpvOpTypeOpaque: + case SpvOpTypePointer: + case SpvOpTypeFunction: + case SpvOpTypeEvent: + case SpvOpTypeDeviceEvent: + case SpvOpTypeReserveId: + case SpvOpTypeQueue: + case SpvOpTypePipe: + case SpvOpTypeForwardPointer: + case SpvOpConstantTrue: + case SpvOpConstantFalse: + case SpvOpConstant: + case SpvOpConstantComposite: + case SpvOpConstantSampler: + case SpvOpConstantNull: + case SpvOpSpecConstantTrue: + case SpvOpSpecConstantFalse: + case SpvOpSpecConstant: + case SpvOpSpecConstantComposite: + case SpvOpSpecConstantOp: + out = false; + break; + default: + out = true; + break; + } + } // clang-format on - - return moduleOrder; + return out; } } namespace libspirv { -ValidationState_t::ValidationState_t(spv_diagnostic* diagnostic, uint32_t options) +ValidationState_t::ValidationState_t(spv_diagnostic* diagnostic, + uint32_t options) : diagnostic_(diagnostic), instruction_counter_(0), defined_ids_{}, @@ -186,15 +263,15 @@ ModuleLayoutSection ValidationState_t::getLayoutStage() const { } void ValidationState_t::progressToNextLayoutStageOrder() { - if (static_cast(current_layout_stage_) <= GetModuleOrder().size()) { + // Guard against going past the last element(kLayoutFunctionDefinitions) + if (current_layout_stage_ <= kLayoutFunctionDefinitions) { current_layout_stage_ = static_cast(current_layout_stage_ + 1); } } bool ValidationState_t::isOpcodeInCurrentLayoutStage(SpvOp op) { - const vector& currentStage = GetModuleOrder()[current_layout_stage_]; - return end(currentStage) != find(begin(currentStage), end(currentStage), op); + return IsInstructionInLayoutSection(current_layout_stage_, op); } DiagnosticStream ValidationState_t::diag(spv_result_t error_code) const { @@ -243,7 +320,8 @@ spv_result_t Functions::RegisterFunction(uint32_t id, uint32_t ret_type_id, spv_result_t Functions::RegisterFunctionParameter(uint32_t id, uint32_t type_id) { assert(in_function_ == true && - "Function parameter instructions cannot be declared outside of a function"); + "Function parameter instructions cannot be declared outside of a " + "function"); if (in_block()) { return module_.diag(SPV_ERROR_INVALID_LAYOUT) << "Function parameters cannot be called in blocks"; @@ -261,7 +339,8 @@ spv_result_t Functions::RegisterFunctionParameter(uint32_t id, } spv_result_t Functions::RegisterSetFunctionDeclType(FunctionDecl type) { - assert(in_function_ == true && "Function can not be declared inside of another function"); + assert(in_function_ == true && + "Function can not be declared inside of another function"); if (declaration_type_.size() <= 1 || type == *(end(declaration_type_) - 2) || type == FunctionDecl::kFunctionDeclDeclaration) { declaration_type_.back() = type;