1fd4e5da5Sopenharmony_ci// Copyright (c) 2015-2016 The Khronos Group Inc. 2fd4e5da5Sopenharmony_ci// 3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 6fd4e5da5Sopenharmony_ci// 7fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8fd4e5da5Sopenharmony_ci// 9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 13fd4e5da5Sopenharmony_ci// limitations under the License. 14fd4e5da5Sopenharmony_ci 15fd4e5da5Sopenharmony_ci#ifndef SOURCE_VAL_VALIDATION_STATE_H_ 16fd4e5da5Sopenharmony_ci#define SOURCE_VAL_VALIDATION_STATE_H_ 17fd4e5da5Sopenharmony_ci 18fd4e5da5Sopenharmony_ci#include <algorithm> 19fd4e5da5Sopenharmony_ci#include <map> 20fd4e5da5Sopenharmony_ci#include <set> 21fd4e5da5Sopenharmony_ci#include <string> 22fd4e5da5Sopenharmony_ci#include <tuple> 23fd4e5da5Sopenharmony_ci#include <unordered_map> 24fd4e5da5Sopenharmony_ci#include <unordered_set> 25fd4e5da5Sopenharmony_ci#include <vector> 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ci#include "source/assembly_grammar.h" 28fd4e5da5Sopenharmony_ci#include "source/diagnostic.h" 29fd4e5da5Sopenharmony_ci#include "source/disassemble.h" 30fd4e5da5Sopenharmony_ci#include "source/enum_set.h" 31fd4e5da5Sopenharmony_ci#include "source/latest_version_spirv_header.h" 32fd4e5da5Sopenharmony_ci#include "source/name_mapper.h" 33fd4e5da5Sopenharmony_ci#include "source/spirv_definition.h" 34fd4e5da5Sopenharmony_ci#include "source/spirv_validator_options.h" 35fd4e5da5Sopenharmony_ci#include "source/val/decoration.h" 36fd4e5da5Sopenharmony_ci#include "source/val/function.h" 37fd4e5da5Sopenharmony_ci#include "source/val/instruction.h" 38fd4e5da5Sopenharmony_ci#include "spirv-tools/libspirv.h" 39fd4e5da5Sopenharmony_ci 40fd4e5da5Sopenharmony_cinamespace spvtools { 41fd4e5da5Sopenharmony_cinamespace val { 42fd4e5da5Sopenharmony_ci 43fd4e5da5Sopenharmony_ci/// This enum represents the sections of a SPIRV module. See section 2.4 44fd4e5da5Sopenharmony_ci/// of the SPIRV spec for additional details of the order. The enumerant values 45fd4e5da5Sopenharmony_ci/// are in the same order as the vector returned by GetModuleOrder 46fd4e5da5Sopenharmony_cienum ModuleLayoutSection { 47fd4e5da5Sopenharmony_ci kLayoutCapabilities, /// < Section 2.4 #1 48fd4e5da5Sopenharmony_ci kLayoutExtensions, /// < Section 2.4 #2 49fd4e5da5Sopenharmony_ci kLayoutExtInstImport, /// < Section 2.4 #3 50fd4e5da5Sopenharmony_ci kLayoutMemoryModel, /// < Section 2.4 #4 51fd4e5da5Sopenharmony_ci kLayoutSamplerImageAddressMode, /// < Section 2.4 #5 52fd4e5da5Sopenharmony_ci kLayoutEntryPoint, /// < Section 2.4 #6 53fd4e5da5Sopenharmony_ci kLayoutExecutionMode, /// < Section 2.4 #7 54fd4e5da5Sopenharmony_ci kLayoutDebug1, /// < Section 2.4 #8 > 1 55fd4e5da5Sopenharmony_ci kLayoutDebug2, /// < Section 2.4 #8 > 2 56fd4e5da5Sopenharmony_ci kLayoutDebug3, /// < Section 2.4 #8 > 3 57fd4e5da5Sopenharmony_ci kLayoutAnnotations, /// < Section 2.4 #9 58fd4e5da5Sopenharmony_ci kLayoutTypes, /// < Section 2.4 #10 59fd4e5da5Sopenharmony_ci kLayoutFunctionDeclarations, /// < Section 2.4 #11 60fd4e5da5Sopenharmony_ci kLayoutFunctionDefinitions /// < Section 2.4 #12 61fd4e5da5Sopenharmony_ci}; 62fd4e5da5Sopenharmony_ci 63fd4e5da5Sopenharmony_ci/// This class manages the state of the SPIR-V validation as it is being parsed. 64fd4e5da5Sopenharmony_ciclass ValidationState_t { 65fd4e5da5Sopenharmony_ci public: 66fd4e5da5Sopenharmony_ci // Features that can optionally be turned on by a capability or environment. 67fd4e5da5Sopenharmony_ci struct Feature { 68fd4e5da5Sopenharmony_ci bool declare_int16_type = false; // Allow OpTypeInt with 16 bit width? 69fd4e5da5Sopenharmony_ci bool declare_float16_type = false; // Allow OpTypeFloat with 16 bit width? 70fd4e5da5Sopenharmony_ci bool free_fp_rounding_mode = false; // Allow the FPRoundingMode decoration 71fd4e5da5Sopenharmony_ci // and its values to be used without 72fd4e5da5Sopenharmony_ci // requiring any capability 73fd4e5da5Sopenharmony_ci 74fd4e5da5Sopenharmony_ci // Allow functionalities enabled by VariablePointers or 75fd4e5da5Sopenharmony_ci // VariablePointersStorageBuffer capability. 76fd4e5da5Sopenharmony_ci bool variable_pointers = false; 77fd4e5da5Sopenharmony_ci 78fd4e5da5Sopenharmony_ci // Permit group oerations Reduce, InclusiveScan, ExclusiveScan 79fd4e5da5Sopenharmony_ci bool group_ops_reduce_and_scans = false; 80fd4e5da5Sopenharmony_ci 81fd4e5da5Sopenharmony_ci // Allow OpTypeInt with 8 bit width? 82fd4e5da5Sopenharmony_ci bool declare_int8_type = false; 83fd4e5da5Sopenharmony_ci 84fd4e5da5Sopenharmony_ci // Target environment uses relaxed block layout. 85fd4e5da5Sopenharmony_ci // This is true for Vulkan 1.1 or later. 86fd4e5da5Sopenharmony_ci bool env_relaxed_block_layout = false; 87fd4e5da5Sopenharmony_ci 88fd4e5da5Sopenharmony_ci // Allow an OpTypeInt with 8 bit width to be used in more than just int 89fd4e5da5Sopenharmony_ci // conversion opcodes 90fd4e5da5Sopenharmony_ci bool use_int8_type = false; 91fd4e5da5Sopenharmony_ci 92fd4e5da5Sopenharmony_ci // SPIR-V 1.4 allows us to select between any two composite values 93fd4e5da5Sopenharmony_ci // of the same type. 94fd4e5da5Sopenharmony_ci bool select_between_composites = false; 95fd4e5da5Sopenharmony_ci 96fd4e5da5Sopenharmony_ci // SPIR-V 1.4 allows two memory access operands for OpCopyMemory and 97fd4e5da5Sopenharmony_ci // OpCopyMemorySized. 98fd4e5da5Sopenharmony_ci bool copy_memory_permits_two_memory_accesses = false; 99fd4e5da5Sopenharmony_ci 100fd4e5da5Sopenharmony_ci // SPIR-V 1.4 allows UConvert as a spec constant op in any environment. 101fd4e5da5Sopenharmony_ci // The Kernel capability already enables it, separately from this flag. 102fd4e5da5Sopenharmony_ci bool uconvert_spec_constant_op = false; 103fd4e5da5Sopenharmony_ci 104fd4e5da5Sopenharmony_ci // SPIR-V 1.4 allows Function and Private variables to be NonWritable 105fd4e5da5Sopenharmony_ci bool nonwritable_var_in_function_or_private = false; 106fd4e5da5Sopenharmony_ci 107fd4e5da5Sopenharmony_ci // Whether LocalSizeId execution mode is allowed by the environment. 108fd4e5da5Sopenharmony_ci bool env_allow_localsizeid = false; 109fd4e5da5Sopenharmony_ci }; 110fd4e5da5Sopenharmony_ci 111fd4e5da5Sopenharmony_ci ValidationState_t(const spv_const_context context, 112fd4e5da5Sopenharmony_ci const spv_const_validator_options opt, 113fd4e5da5Sopenharmony_ci const uint32_t* words, const size_t num_words, 114fd4e5da5Sopenharmony_ci const uint32_t max_warnings); 115fd4e5da5Sopenharmony_ci 116fd4e5da5Sopenharmony_ci /// Returns the context 117fd4e5da5Sopenharmony_ci spv_const_context context() const { return context_; } 118fd4e5da5Sopenharmony_ci 119fd4e5da5Sopenharmony_ci /// Returns the command line options 120fd4e5da5Sopenharmony_ci spv_const_validator_options options() const { return options_; } 121fd4e5da5Sopenharmony_ci 122fd4e5da5Sopenharmony_ci /// Sets the ID of the generator for this module. 123fd4e5da5Sopenharmony_ci void setGenerator(uint32_t gen) { generator_ = gen; } 124fd4e5da5Sopenharmony_ci 125fd4e5da5Sopenharmony_ci /// Returns the ID of the generator for this module. 126fd4e5da5Sopenharmony_ci uint32_t generator() const { return generator_; } 127fd4e5da5Sopenharmony_ci 128fd4e5da5Sopenharmony_ci /// Sets the SPIR-V version of this module. 129fd4e5da5Sopenharmony_ci void setVersion(uint32_t ver) { version_ = ver; } 130fd4e5da5Sopenharmony_ci 131fd4e5da5Sopenharmony_ci /// Gets the SPIR-V version of this module. 132fd4e5da5Sopenharmony_ci uint32_t version() const { return version_; } 133fd4e5da5Sopenharmony_ci 134fd4e5da5Sopenharmony_ci /// Forward declares the id in the module 135fd4e5da5Sopenharmony_ci spv_result_t ForwardDeclareId(uint32_t id); 136fd4e5da5Sopenharmony_ci 137fd4e5da5Sopenharmony_ci /// Removes a forward declared ID if it has been defined 138fd4e5da5Sopenharmony_ci spv_result_t RemoveIfForwardDeclared(uint32_t id); 139fd4e5da5Sopenharmony_ci 140fd4e5da5Sopenharmony_ci /// Registers an ID as a forward pointer 141fd4e5da5Sopenharmony_ci spv_result_t RegisterForwardPointer(uint32_t id); 142fd4e5da5Sopenharmony_ci 143fd4e5da5Sopenharmony_ci /// Returns whether or not an ID is a forward pointer 144fd4e5da5Sopenharmony_ci bool IsForwardPointer(uint32_t id) const; 145fd4e5da5Sopenharmony_ci 146fd4e5da5Sopenharmony_ci /// Assigns a name to an ID 147fd4e5da5Sopenharmony_ci void AssignNameToId(uint32_t id, std::string name); 148fd4e5da5Sopenharmony_ci 149fd4e5da5Sopenharmony_ci /// Returns a string representation of the ID in the format <id>[Name] where 150fd4e5da5Sopenharmony_ci /// the <id> is the numeric valid of the id and the Name is a name assigned by 151fd4e5da5Sopenharmony_ci /// the OpName instruction 152fd4e5da5Sopenharmony_ci std::string getIdName(uint32_t id) const; 153fd4e5da5Sopenharmony_ci 154fd4e5da5Sopenharmony_ci /// Accessor function for ID bound. 155fd4e5da5Sopenharmony_ci uint32_t getIdBound() const; 156fd4e5da5Sopenharmony_ci 157fd4e5da5Sopenharmony_ci /// Mutator function for ID bound. 158fd4e5da5Sopenharmony_ci void setIdBound(uint32_t bound); 159fd4e5da5Sopenharmony_ci 160fd4e5da5Sopenharmony_ci /// Returns the number of ID which have been forward referenced but not 161fd4e5da5Sopenharmony_ci /// defined 162fd4e5da5Sopenharmony_ci size_t unresolved_forward_id_count() const; 163fd4e5da5Sopenharmony_ci 164fd4e5da5Sopenharmony_ci /// Returns a vector of unresolved forward ids. 165fd4e5da5Sopenharmony_ci std::vector<uint32_t> UnresolvedForwardIds() const; 166fd4e5da5Sopenharmony_ci 167fd4e5da5Sopenharmony_ci /// Returns true if the id has been defined 168fd4e5da5Sopenharmony_ci bool IsDefinedId(uint32_t id) const; 169fd4e5da5Sopenharmony_ci 170fd4e5da5Sopenharmony_ci /// Increments the total number of instructions in the file. 171fd4e5da5Sopenharmony_ci void increment_total_instructions() { total_instructions_++; } 172fd4e5da5Sopenharmony_ci 173fd4e5da5Sopenharmony_ci /// Increments the total number of functions in the file. 174fd4e5da5Sopenharmony_ci void increment_total_functions() { total_functions_++; } 175fd4e5da5Sopenharmony_ci 176fd4e5da5Sopenharmony_ci /// Allocates internal storage. Note, calling this will invalidate any 177fd4e5da5Sopenharmony_ci /// pointers to |ordered_instructions_| or |module_functions_| and, hence, 178fd4e5da5Sopenharmony_ci /// should only be called at the beginning of validation. 179fd4e5da5Sopenharmony_ci void preallocateStorage(); 180fd4e5da5Sopenharmony_ci 181fd4e5da5Sopenharmony_ci /// Returns the current layout section which is being processed 182fd4e5da5Sopenharmony_ci ModuleLayoutSection current_layout_section() const; 183fd4e5da5Sopenharmony_ci 184fd4e5da5Sopenharmony_ci /// Increments the module_layout_order_section_ 185fd4e5da5Sopenharmony_ci void ProgressToNextLayoutSectionOrder(); 186fd4e5da5Sopenharmony_ci 187fd4e5da5Sopenharmony_ci /// Determines if the op instruction is in a previous layout section 188fd4e5da5Sopenharmony_ci bool IsOpcodeInPreviousLayoutSection(spv::Op op); 189fd4e5da5Sopenharmony_ci 190fd4e5da5Sopenharmony_ci /// Determines if the op instruction is part of the current section 191fd4e5da5Sopenharmony_ci bool IsOpcodeInCurrentLayoutSection(spv::Op op); 192fd4e5da5Sopenharmony_ci 193fd4e5da5Sopenharmony_ci DiagnosticStream diag(spv_result_t error_code, const Instruction* inst); 194fd4e5da5Sopenharmony_ci 195fd4e5da5Sopenharmony_ci /// Returns the function states 196fd4e5da5Sopenharmony_ci std::vector<Function>& functions(); 197fd4e5da5Sopenharmony_ci 198fd4e5da5Sopenharmony_ci /// Returns the function states 199fd4e5da5Sopenharmony_ci Function& current_function(); 200fd4e5da5Sopenharmony_ci const Function& current_function() const; 201fd4e5da5Sopenharmony_ci 202fd4e5da5Sopenharmony_ci /// Returns function state with the given id, or nullptr if no such function. 203fd4e5da5Sopenharmony_ci const Function* function(uint32_t id) const; 204fd4e5da5Sopenharmony_ci Function* function(uint32_t id); 205fd4e5da5Sopenharmony_ci 206fd4e5da5Sopenharmony_ci /// Returns true if the called after a function instruction but before the 207fd4e5da5Sopenharmony_ci /// function end instruction 208fd4e5da5Sopenharmony_ci bool in_function_body() const; 209fd4e5da5Sopenharmony_ci 210fd4e5da5Sopenharmony_ci /// Returns true if called after a label instruction but before a branch 211fd4e5da5Sopenharmony_ci /// instruction 212fd4e5da5Sopenharmony_ci bool in_block() const; 213fd4e5da5Sopenharmony_ci 214fd4e5da5Sopenharmony_ci struct EntryPointDescription { 215fd4e5da5Sopenharmony_ci std::string name; 216fd4e5da5Sopenharmony_ci std::vector<uint32_t> interfaces; 217fd4e5da5Sopenharmony_ci }; 218fd4e5da5Sopenharmony_ci 219fd4e5da5Sopenharmony_ci /// Registers |id| as an entry point with |execution_model| and |interfaces|. 220fd4e5da5Sopenharmony_ci void RegisterEntryPoint(const uint32_t id, 221fd4e5da5Sopenharmony_ci spv::ExecutionModel execution_model, 222fd4e5da5Sopenharmony_ci EntryPointDescription&& desc) { 223fd4e5da5Sopenharmony_ci entry_points_.push_back(id); 224fd4e5da5Sopenharmony_ci entry_point_to_execution_models_[id].insert(execution_model); 225fd4e5da5Sopenharmony_ci entry_point_descriptions_[id].emplace_back(desc); 226fd4e5da5Sopenharmony_ci } 227fd4e5da5Sopenharmony_ci 228fd4e5da5Sopenharmony_ci /// Returns a list of entry point function ids 229fd4e5da5Sopenharmony_ci const std::vector<uint32_t>& entry_points() const { return entry_points_; } 230fd4e5da5Sopenharmony_ci 231fd4e5da5Sopenharmony_ci /// Returns the set of entry points that root call graphs that contain 232fd4e5da5Sopenharmony_ci /// recursion. 233fd4e5da5Sopenharmony_ci const std::set<uint32_t>& recursive_entry_points() const { 234fd4e5da5Sopenharmony_ci return recursive_entry_points_; 235fd4e5da5Sopenharmony_ci } 236fd4e5da5Sopenharmony_ci 237fd4e5da5Sopenharmony_ci /// Registers execution mode for the given entry point. 238fd4e5da5Sopenharmony_ci void RegisterExecutionModeForEntryPoint(uint32_t entry_point, 239fd4e5da5Sopenharmony_ci spv::ExecutionMode execution_mode) { 240fd4e5da5Sopenharmony_ci entry_point_to_execution_modes_[entry_point].insert(execution_mode); 241fd4e5da5Sopenharmony_ci } 242fd4e5da5Sopenharmony_ci 243fd4e5da5Sopenharmony_ci /// Returns the interface descriptions of a given entry point. 244fd4e5da5Sopenharmony_ci const std::vector<EntryPointDescription>& entry_point_descriptions( 245fd4e5da5Sopenharmony_ci uint32_t entry_point) { 246fd4e5da5Sopenharmony_ci return entry_point_descriptions_.at(entry_point); 247fd4e5da5Sopenharmony_ci } 248fd4e5da5Sopenharmony_ci 249fd4e5da5Sopenharmony_ci /// Returns Execution Models for the given Entry Point. 250fd4e5da5Sopenharmony_ci /// Returns nullptr if none found (would trigger assertion). 251fd4e5da5Sopenharmony_ci const std::set<spv::ExecutionModel>* GetExecutionModels( 252fd4e5da5Sopenharmony_ci uint32_t entry_point) const { 253fd4e5da5Sopenharmony_ci const auto it = entry_point_to_execution_models_.find(entry_point); 254fd4e5da5Sopenharmony_ci if (it == entry_point_to_execution_models_.end()) { 255fd4e5da5Sopenharmony_ci assert(0); 256fd4e5da5Sopenharmony_ci return nullptr; 257fd4e5da5Sopenharmony_ci } 258fd4e5da5Sopenharmony_ci return &it->second; 259fd4e5da5Sopenharmony_ci } 260fd4e5da5Sopenharmony_ci 261fd4e5da5Sopenharmony_ci /// Returns Execution Modes for the given Entry Point. 262fd4e5da5Sopenharmony_ci /// Returns nullptr if none found. 263fd4e5da5Sopenharmony_ci const std::set<spv::ExecutionMode>* GetExecutionModes( 264fd4e5da5Sopenharmony_ci uint32_t entry_point) const { 265fd4e5da5Sopenharmony_ci const auto it = entry_point_to_execution_modes_.find(entry_point); 266fd4e5da5Sopenharmony_ci if (it == entry_point_to_execution_modes_.end()) { 267fd4e5da5Sopenharmony_ci return nullptr; 268fd4e5da5Sopenharmony_ci } 269fd4e5da5Sopenharmony_ci return &it->second; 270fd4e5da5Sopenharmony_ci } 271fd4e5da5Sopenharmony_ci 272fd4e5da5Sopenharmony_ci /// Traverses call tree and computes function_to_entry_points_. 273fd4e5da5Sopenharmony_ci /// Note: called after fully parsing the binary. 274fd4e5da5Sopenharmony_ci void ComputeFunctionToEntryPointMapping(); 275fd4e5da5Sopenharmony_ci 276fd4e5da5Sopenharmony_ci /// Traverse call tree and computes recursive_entry_points_. 277fd4e5da5Sopenharmony_ci /// Note: called after fully parsing the binary and calling 278fd4e5da5Sopenharmony_ci /// ComputeFunctionToEntryPointMapping. 279fd4e5da5Sopenharmony_ci void ComputeRecursiveEntryPoints(); 280fd4e5da5Sopenharmony_ci 281fd4e5da5Sopenharmony_ci /// Returns all the entry points that can call |func|. 282fd4e5da5Sopenharmony_ci const std::vector<uint32_t>& FunctionEntryPoints(uint32_t func) const; 283fd4e5da5Sopenharmony_ci 284fd4e5da5Sopenharmony_ci /// Returns all the entry points that statically use |id|. 285fd4e5da5Sopenharmony_ci /// 286fd4e5da5Sopenharmony_ci /// Note: requires ComputeFunctionToEntryPointMapping to have been called. 287fd4e5da5Sopenharmony_ci std::set<uint32_t> EntryPointReferences(uint32_t id) const; 288fd4e5da5Sopenharmony_ci 289fd4e5da5Sopenharmony_ci /// Inserts an <id> to the set of functions that are target of OpFunctionCall. 290fd4e5da5Sopenharmony_ci void AddFunctionCallTarget(const uint32_t id) { 291fd4e5da5Sopenharmony_ci function_call_targets_.insert(id); 292fd4e5da5Sopenharmony_ci current_function().AddFunctionCallTarget(id); 293fd4e5da5Sopenharmony_ci } 294fd4e5da5Sopenharmony_ci 295fd4e5da5Sopenharmony_ci /// Returns whether or not a function<id> is the target of OpFunctionCall. 296fd4e5da5Sopenharmony_ci bool IsFunctionCallTarget(const uint32_t id) { 297fd4e5da5Sopenharmony_ci return (function_call_targets_.find(id) != function_call_targets_.end()); 298fd4e5da5Sopenharmony_ci } 299fd4e5da5Sopenharmony_ci 300fd4e5da5Sopenharmony_ci bool IsFunctionCallDefined(const uint32_t id) { 301fd4e5da5Sopenharmony_ci return (id_to_function_.find(id) != id_to_function_.end()); 302fd4e5da5Sopenharmony_ci } 303fd4e5da5Sopenharmony_ci /// Registers the capability and its dependent capabilities 304fd4e5da5Sopenharmony_ci void RegisterCapability(spv::Capability cap); 305fd4e5da5Sopenharmony_ci 306fd4e5da5Sopenharmony_ci /// Registers the extension. 307fd4e5da5Sopenharmony_ci void RegisterExtension(Extension ext); 308fd4e5da5Sopenharmony_ci 309fd4e5da5Sopenharmony_ci /// Registers the function in the module. Subsequent instructions will be 310fd4e5da5Sopenharmony_ci /// called against this function 311fd4e5da5Sopenharmony_ci spv_result_t RegisterFunction(uint32_t id, uint32_t ret_type_id, 312fd4e5da5Sopenharmony_ci spv::FunctionControlMask function_control, 313fd4e5da5Sopenharmony_ci uint32_t function_type_id); 314fd4e5da5Sopenharmony_ci 315fd4e5da5Sopenharmony_ci /// Register a function end instruction 316fd4e5da5Sopenharmony_ci spv_result_t RegisterFunctionEnd(); 317fd4e5da5Sopenharmony_ci 318fd4e5da5Sopenharmony_ci /// Returns true if the capability is enabled in the module. 319fd4e5da5Sopenharmony_ci bool HasCapability(spv::Capability cap) const { 320fd4e5da5Sopenharmony_ci return module_capabilities_.contains(cap); 321fd4e5da5Sopenharmony_ci } 322fd4e5da5Sopenharmony_ci 323fd4e5da5Sopenharmony_ci /// Returns a reference to the set of capabilities in the module. 324fd4e5da5Sopenharmony_ci /// This is provided for debuggability. 325fd4e5da5Sopenharmony_ci const CapabilitySet& module_capabilities() const { 326fd4e5da5Sopenharmony_ci return module_capabilities_; 327fd4e5da5Sopenharmony_ci } 328fd4e5da5Sopenharmony_ci 329fd4e5da5Sopenharmony_ci /// Returns true if the extension is enabled in the module. 330fd4e5da5Sopenharmony_ci bool HasExtension(Extension ext) const { 331fd4e5da5Sopenharmony_ci return module_extensions_.contains(ext); 332fd4e5da5Sopenharmony_ci } 333fd4e5da5Sopenharmony_ci 334fd4e5da5Sopenharmony_ci /// Returns true if any of the capabilities is enabled, or if |capabilities| 335fd4e5da5Sopenharmony_ci /// is an empty set. 336fd4e5da5Sopenharmony_ci bool HasAnyOfCapabilities(const CapabilitySet& capabilities) const; 337fd4e5da5Sopenharmony_ci 338fd4e5da5Sopenharmony_ci /// Returns true if any of the extensions is enabled, or if |extensions| 339fd4e5da5Sopenharmony_ci /// is an empty set. 340fd4e5da5Sopenharmony_ci bool HasAnyOfExtensions(const ExtensionSet& extensions) const; 341fd4e5da5Sopenharmony_ci 342fd4e5da5Sopenharmony_ci /// Sets the addressing model of this module (logical/physical). 343fd4e5da5Sopenharmony_ci void set_addressing_model(spv::AddressingModel am); 344fd4e5da5Sopenharmony_ci 345fd4e5da5Sopenharmony_ci /// Returns true if the OpMemoryModel was found. 346fd4e5da5Sopenharmony_ci bool has_memory_model_specified() const { 347fd4e5da5Sopenharmony_ci return addressing_model_ != spv::AddressingModel::Max && 348fd4e5da5Sopenharmony_ci memory_model_ != spv::MemoryModel::Max; 349fd4e5da5Sopenharmony_ci } 350fd4e5da5Sopenharmony_ci 351fd4e5da5Sopenharmony_ci /// Returns the addressing model of this module, or Logical if uninitialized. 352fd4e5da5Sopenharmony_ci spv::AddressingModel addressing_model() const; 353fd4e5da5Sopenharmony_ci 354fd4e5da5Sopenharmony_ci /// Returns the addressing model of this module, or Logical if uninitialized. 355fd4e5da5Sopenharmony_ci uint32_t pointer_size_and_alignment() const { 356fd4e5da5Sopenharmony_ci return pointer_size_and_alignment_; 357fd4e5da5Sopenharmony_ci } 358fd4e5da5Sopenharmony_ci 359fd4e5da5Sopenharmony_ci /// Sets the memory model of this module. 360fd4e5da5Sopenharmony_ci void set_memory_model(spv::MemoryModel mm); 361fd4e5da5Sopenharmony_ci 362fd4e5da5Sopenharmony_ci /// Returns the memory model of this module, or Simple if uninitialized. 363fd4e5da5Sopenharmony_ci spv::MemoryModel memory_model() const; 364fd4e5da5Sopenharmony_ci 365fd4e5da5Sopenharmony_ci /// Sets the bit width for sampler/image type variables. If not set, they are 366fd4e5da5Sopenharmony_ci /// considered opaque 367fd4e5da5Sopenharmony_ci void set_samplerimage_variable_address_mode(uint32_t bit_width); 368fd4e5da5Sopenharmony_ci 369fd4e5da5Sopenharmony_ci /// Get the addressing mode currently set. If 0, it means addressing mode is 370fd4e5da5Sopenharmony_ci /// invalid Sampler/Image type variables must be considered opaque This mode 371fd4e5da5Sopenharmony_ci /// is only valid after the instruction has been read 372fd4e5da5Sopenharmony_ci uint32_t samplerimage_variable_address_mode() const; 373fd4e5da5Sopenharmony_ci 374fd4e5da5Sopenharmony_ci /// Returns true if the OpSamplerImageAddressingModeNV was found. 375fd4e5da5Sopenharmony_ci bool has_samplerimage_variable_address_mode_specified() const { 376fd4e5da5Sopenharmony_ci return sampler_image_addressing_mode_ != 0; 377fd4e5da5Sopenharmony_ci } 378fd4e5da5Sopenharmony_ci 379fd4e5da5Sopenharmony_ci const AssemblyGrammar& grammar() const { return grammar_; } 380fd4e5da5Sopenharmony_ci 381fd4e5da5Sopenharmony_ci /// Inserts the instruction into the list of ordered instructions in the file. 382fd4e5da5Sopenharmony_ci Instruction* AddOrderedInstruction(const spv_parsed_instruction_t* inst); 383fd4e5da5Sopenharmony_ci 384fd4e5da5Sopenharmony_ci /// Registers the instruction. This will add the instruction to the list of 385fd4e5da5Sopenharmony_ci /// definitions and register sampled image consumers. 386fd4e5da5Sopenharmony_ci void RegisterInstruction(Instruction* inst); 387fd4e5da5Sopenharmony_ci 388fd4e5da5Sopenharmony_ci /// Registers the debug instruction information. 389fd4e5da5Sopenharmony_ci void RegisterDebugInstruction(const Instruction* inst); 390fd4e5da5Sopenharmony_ci 391fd4e5da5Sopenharmony_ci /// Registers the decoration for the given <id> 392fd4e5da5Sopenharmony_ci void RegisterDecorationForId(uint32_t id, const Decoration& dec) { 393fd4e5da5Sopenharmony_ci auto& dec_list = id_decorations_[id]; 394fd4e5da5Sopenharmony_ci dec_list.insert(dec); 395fd4e5da5Sopenharmony_ci } 396fd4e5da5Sopenharmony_ci 397fd4e5da5Sopenharmony_ci /// Registers the list of decorations for the given <id> 398fd4e5da5Sopenharmony_ci template <class InputIt> 399fd4e5da5Sopenharmony_ci void RegisterDecorationsForId(uint32_t id, InputIt begin, InputIt end) { 400fd4e5da5Sopenharmony_ci std::set<Decoration>& cur_decs = id_decorations_[id]; 401fd4e5da5Sopenharmony_ci cur_decs.insert(begin, end); 402fd4e5da5Sopenharmony_ci } 403fd4e5da5Sopenharmony_ci 404fd4e5da5Sopenharmony_ci /// Registers the list of decorations for the given member of the given 405fd4e5da5Sopenharmony_ci /// structure. 406fd4e5da5Sopenharmony_ci template <class InputIt> 407fd4e5da5Sopenharmony_ci void RegisterDecorationsForStructMember(uint32_t struct_id, 408fd4e5da5Sopenharmony_ci uint32_t member_index, InputIt begin, 409fd4e5da5Sopenharmony_ci InputIt end) { 410fd4e5da5Sopenharmony_ci std::set<Decoration>& cur_decs = id_decorations_[struct_id]; 411fd4e5da5Sopenharmony_ci for (InputIt iter = begin; iter != end; ++iter) { 412fd4e5da5Sopenharmony_ci Decoration dec = *iter; 413fd4e5da5Sopenharmony_ci dec.set_struct_member_index(member_index); 414fd4e5da5Sopenharmony_ci cur_decs.insert(dec); 415fd4e5da5Sopenharmony_ci } 416fd4e5da5Sopenharmony_ci } 417fd4e5da5Sopenharmony_ci 418fd4e5da5Sopenharmony_ci /// Returns all the decorations for the given <id>. If no decorations exist 419fd4e5da5Sopenharmony_ci /// for the <id>, it registers an empty set for it in the map and 420fd4e5da5Sopenharmony_ci /// returns the empty set. 421fd4e5da5Sopenharmony_ci std::set<Decoration>& id_decorations(uint32_t id) { 422fd4e5da5Sopenharmony_ci return id_decorations_[id]; 423fd4e5da5Sopenharmony_ci } 424fd4e5da5Sopenharmony_ci 425fd4e5da5Sopenharmony_ci /// Returns the range of decorations for the given field of the given <id>. 426fd4e5da5Sopenharmony_ci struct FieldDecorationsIter { 427fd4e5da5Sopenharmony_ci std::set<Decoration>::const_iterator begin; 428fd4e5da5Sopenharmony_ci std::set<Decoration>::const_iterator end; 429fd4e5da5Sopenharmony_ci }; 430fd4e5da5Sopenharmony_ci FieldDecorationsIter id_member_decorations(uint32_t id, 431fd4e5da5Sopenharmony_ci uint32_t member_index) { 432fd4e5da5Sopenharmony_ci const auto& decorations = id_decorations_[id]; 433fd4e5da5Sopenharmony_ci 434fd4e5da5Sopenharmony_ci // The decorations are sorted by member_index, so this look up will give the 435fd4e5da5Sopenharmony_ci // exact range of decorations for this member index. 436fd4e5da5Sopenharmony_ci Decoration min_decoration((spv::Decoration)0, {}, member_index); 437fd4e5da5Sopenharmony_ci Decoration max_decoration(spv::Decoration::Max, {}, member_index); 438fd4e5da5Sopenharmony_ci 439fd4e5da5Sopenharmony_ci FieldDecorationsIter result; 440fd4e5da5Sopenharmony_ci result.begin = decorations.lower_bound(min_decoration); 441fd4e5da5Sopenharmony_ci result.end = decorations.upper_bound(max_decoration); 442fd4e5da5Sopenharmony_ci 443fd4e5da5Sopenharmony_ci return result; 444fd4e5da5Sopenharmony_ci } 445fd4e5da5Sopenharmony_ci 446fd4e5da5Sopenharmony_ci // Returns const pointer to the internal decoration container. 447fd4e5da5Sopenharmony_ci const std::map<uint32_t, std::set<Decoration>>& id_decorations() const { 448fd4e5da5Sopenharmony_ci return id_decorations_; 449fd4e5da5Sopenharmony_ci } 450fd4e5da5Sopenharmony_ci 451fd4e5da5Sopenharmony_ci /// Returns true if the given id <id> has the given decoration <dec>, 452fd4e5da5Sopenharmony_ci /// otherwise returns false. 453fd4e5da5Sopenharmony_ci bool HasDecoration(uint32_t id, spv::Decoration dec) { 454fd4e5da5Sopenharmony_ci const auto& decorations = id_decorations_.find(id); 455fd4e5da5Sopenharmony_ci if (decorations == id_decorations_.end()) return false; 456fd4e5da5Sopenharmony_ci 457fd4e5da5Sopenharmony_ci return std::any_of( 458fd4e5da5Sopenharmony_ci decorations->second.begin(), decorations->second.end(), 459fd4e5da5Sopenharmony_ci [dec](const Decoration& d) { return dec == d.dec_type(); }); 460fd4e5da5Sopenharmony_ci } 461fd4e5da5Sopenharmony_ci 462fd4e5da5Sopenharmony_ci /// Finds id's def, if it exists. If found, returns the definition otherwise 463fd4e5da5Sopenharmony_ci /// nullptr 464fd4e5da5Sopenharmony_ci const Instruction* FindDef(uint32_t id) const; 465fd4e5da5Sopenharmony_ci 466fd4e5da5Sopenharmony_ci /// Finds id's def, if it exists. If found, returns the definition otherwise 467fd4e5da5Sopenharmony_ci /// nullptr 468fd4e5da5Sopenharmony_ci Instruction* FindDef(uint32_t id); 469fd4e5da5Sopenharmony_ci 470fd4e5da5Sopenharmony_ci /// Returns the instructions in the order they appear in the binary 471fd4e5da5Sopenharmony_ci const std::vector<Instruction>& ordered_instructions() const { 472fd4e5da5Sopenharmony_ci return ordered_instructions_; 473fd4e5da5Sopenharmony_ci } 474fd4e5da5Sopenharmony_ci 475fd4e5da5Sopenharmony_ci /// Returns a map of instructions mapped by their result id 476fd4e5da5Sopenharmony_ci const std::unordered_map<uint32_t, Instruction*>& all_definitions() const { 477fd4e5da5Sopenharmony_ci return all_definitions_; 478fd4e5da5Sopenharmony_ci } 479fd4e5da5Sopenharmony_ci 480fd4e5da5Sopenharmony_ci /// Returns a vector containing the instructions that consume the given 481fd4e5da5Sopenharmony_ci /// SampledImage id. 482fd4e5da5Sopenharmony_ci std::vector<Instruction*> getSampledImageConsumers(uint32_t id) const; 483fd4e5da5Sopenharmony_ci 484fd4e5da5Sopenharmony_ci /// Records cons_id as a consumer of sampled_image_id. 485fd4e5da5Sopenharmony_ci void RegisterSampledImageConsumer(uint32_t sampled_image_id, 486fd4e5da5Sopenharmony_ci Instruction* consumer); 487fd4e5da5Sopenharmony_ci 488fd4e5da5Sopenharmony_ci // Record a cons_id as a consumer of texture_id 489fd4e5da5Sopenharmony_ci // if texture 'texture_id' has a QCOM image processing decoration 490fd4e5da5Sopenharmony_ci // and consumer is a load or a sampled image instruction 491fd4e5da5Sopenharmony_ci void RegisterQCOMImageProcessingTextureConsumer(uint32_t texture_id, 492fd4e5da5Sopenharmony_ci const Instruction* consumer0, 493fd4e5da5Sopenharmony_ci const Instruction* consumer1); 494fd4e5da5Sopenharmony_ci 495fd4e5da5Sopenharmony_ci // Record a function's storage class consumer instruction 496fd4e5da5Sopenharmony_ci void RegisterStorageClassConsumer(spv::StorageClass storage_class, 497fd4e5da5Sopenharmony_ci Instruction* consumer); 498fd4e5da5Sopenharmony_ci 499fd4e5da5Sopenharmony_ci /// Returns the set of Global Variables. 500fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t>& global_vars() { return global_vars_; } 501fd4e5da5Sopenharmony_ci 502fd4e5da5Sopenharmony_ci /// Returns the set of Local Variables. 503fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t>& local_vars() { return local_vars_; } 504fd4e5da5Sopenharmony_ci 505fd4e5da5Sopenharmony_ci /// Returns the number of Global Variables. 506fd4e5da5Sopenharmony_ci size_t num_global_vars() { return global_vars_.size(); } 507fd4e5da5Sopenharmony_ci 508fd4e5da5Sopenharmony_ci /// Returns the number of Local Variables. 509fd4e5da5Sopenharmony_ci size_t num_local_vars() { return local_vars_.size(); } 510fd4e5da5Sopenharmony_ci 511fd4e5da5Sopenharmony_ci /// Inserts a new <id> to the set of Global Variables. 512fd4e5da5Sopenharmony_ci void registerGlobalVariable(const uint32_t id) { global_vars_.insert(id); } 513fd4e5da5Sopenharmony_ci 514fd4e5da5Sopenharmony_ci /// Inserts a new <id> to the set of Local Variables. 515fd4e5da5Sopenharmony_ci void registerLocalVariable(const uint32_t id) { local_vars_.insert(id); } 516fd4e5da5Sopenharmony_ci 517fd4e5da5Sopenharmony_ci // Returns true if using relaxed block layout, equivalent to 518fd4e5da5Sopenharmony_ci // VK_KHR_relaxed_block_layout. 519fd4e5da5Sopenharmony_ci bool IsRelaxedBlockLayout() const { 520fd4e5da5Sopenharmony_ci return features_.env_relaxed_block_layout || options()->relax_block_layout; 521fd4e5da5Sopenharmony_ci } 522fd4e5da5Sopenharmony_ci 523fd4e5da5Sopenharmony_ci // Returns true if allowing localsizeid, either because the environment always 524fd4e5da5Sopenharmony_ci // allows it, or because it is enabled from the command-line. 525fd4e5da5Sopenharmony_ci bool IsLocalSizeIdAllowed() const { 526fd4e5da5Sopenharmony_ci return features_.env_allow_localsizeid || options()->allow_localsizeid; 527fd4e5da5Sopenharmony_ci } 528fd4e5da5Sopenharmony_ci 529fd4e5da5Sopenharmony_ci /// Sets the struct nesting depth for a given struct ID 530fd4e5da5Sopenharmony_ci void set_struct_nesting_depth(uint32_t id, uint32_t depth) { 531fd4e5da5Sopenharmony_ci struct_nesting_depth_[id] = depth; 532fd4e5da5Sopenharmony_ci } 533fd4e5da5Sopenharmony_ci 534fd4e5da5Sopenharmony_ci /// Returns the nesting depth of a given structure ID 535fd4e5da5Sopenharmony_ci uint32_t struct_nesting_depth(uint32_t id) { 536fd4e5da5Sopenharmony_ci return struct_nesting_depth_[id]; 537fd4e5da5Sopenharmony_ci } 538fd4e5da5Sopenharmony_ci 539fd4e5da5Sopenharmony_ci /// Records the has a nested block/bufferblock decorated struct for a given 540fd4e5da5Sopenharmony_ci /// struct ID 541fd4e5da5Sopenharmony_ci void SetHasNestedBlockOrBufferBlockStruct(uint32_t id, bool has) { 542fd4e5da5Sopenharmony_ci struct_has_nested_blockorbufferblock_struct_[id] = has; 543fd4e5da5Sopenharmony_ci } 544fd4e5da5Sopenharmony_ci 545fd4e5da5Sopenharmony_ci /// For a given struct ID returns true if it has a nested block/bufferblock 546fd4e5da5Sopenharmony_ci /// decorated struct 547fd4e5da5Sopenharmony_ci bool GetHasNestedBlockOrBufferBlockStruct(uint32_t id) { 548fd4e5da5Sopenharmony_ci return struct_has_nested_blockorbufferblock_struct_[id]; 549fd4e5da5Sopenharmony_ci } 550fd4e5da5Sopenharmony_ci 551fd4e5da5Sopenharmony_ci /// Records that the structure type has a member decorated with a built-in. 552fd4e5da5Sopenharmony_ci void RegisterStructTypeWithBuiltInMember(uint32_t id) { 553fd4e5da5Sopenharmony_ci builtin_structs_.insert(id); 554fd4e5da5Sopenharmony_ci } 555fd4e5da5Sopenharmony_ci 556fd4e5da5Sopenharmony_ci /// Returns true if the struct type with the given Id has a BuiltIn member. 557fd4e5da5Sopenharmony_ci bool IsStructTypeWithBuiltInMember(uint32_t id) const { 558fd4e5da5Sopenharmony_ci return (builtin_structs_.find(id) != builtin_structs_.end()); 559fd4e5da5Sopenharmony_ci } 560fd4e5da5Sopenharmony_ci 561fd4e5da5Sopenharmony_ci // Returns the state of optional features. 562fd4e5da5Sopenharmony_ci const Feature& features() const { return features_; } 563fd4e5da5Sopenharmony_ci 564fd4e5da5Sopenharmony_ci /// Adds the instruction data to unique_type_declarations_. 565fd4e5da5Sopenharmony_ci /// Returns false if an identical type declaration already exists. 566fd4e5da5Sopenharmony_ci bool RegisterUniqueTypeDeclaration(const Instruction* inst); 567fd4e5da5Sopenharmony_ci 568fd4e5da5Sopenharmony_ci // Returns type_id of the scalar component of |id|. 569fd4e5da5Sopenharmony_ci // |id| can be either 570fd4e5da5Sopenharmony_ci // - scalar, vector or matrix type 571fd4e5da5Sopenharmony_ci // - object of either scalar, vector or matrix type 572fd4e5da5Sopenharmony_ci uint32_t GetComponentType(uint32_t id) const; 573fd4e5da5Sopenharmony_ci 574fd4e5da5Sopenharmony_ci // Returns 575fd4e5da5Sopenharmony_ci // - 1 for scalar types or objects 576fd4e5da5Sopenharmony_ci // - vector size for vector types or objects 577fd4e5da5Sopenharmony_ci // - num columns for matrix types or objects 578fd4e5da5Sopenharmony_ci // Should not be called with any other arguments (will return zero and invoke 579fd4e5da5Sopenharmony_ci // assertion). 580fd4e5da5Sopenharmony_ci uint32_t GetDimension(uint32_t id) const; 581fd4e5da5Sopenharmony_ci 582fd4e5da5Sopenharmony_ci // Returns bit width of scalar or component. 583fd4e5da5Sopenharmony_ci // |id| can be 584fd4e5da5Sopenharmony_ci // - scalar, vector or matrix type 585fd4e5da5Sopenharmony_ci // - object of either scalar, vector or matrix type 586fd4e5da5Sopenharmony_ci // Will invoke assertion and return 0 if |id| is none of the above. 587fd4e5da5Sopenharmony_ci uint32_t GetBitWidth(uint32_t id) const; 588fd4e5da5Sopenharmony_ci 589fd4e5da5Sopenharmony_ci // Provides detailed information on matrix type. 590fd4e5da5Sopenharmony_ci // Returns false iff |id| is not matrix type. 591fd4e5da5Sopenharmony_ci bool GetMatrixTypeInfo(uint32_t id, uint32_t* num_rows, uint32_t* num_cols, 592fd4e5da5Sopenharmony_ci uint32_t* column_type, uint32_t* component_type) const; 593fd4e5da5Sopenharmony_ci 594fd4e5da5Sopenharmony_ci // Collects struct member types into |member_types|. 595fd4e5da5Sopenharmony_ci // Returns false iff not struct type or has no members. 596fd4e5da5Sopenharmony_ci // Deletes prior contents of |member_types|. 597fd4e5da5Sopenharmony_ci bool GetStructMemberTypes(uint32_t struct_type_id, 598fd4e5da5Sopenharmony_ci std::vector<uint32_t>* member_types) const; 599fd4e5da5Sopenharmony_ci 600fd4e5da5Sopenharmony_ci // Returns true iff |id| is a type corresponding to the name of the function. 601fd4e5da5Sopenharmony_ci // Only works for types not for objects. 602fd4e5da5Sopenharmony_ci bool IsVoidType(uint32_t id) const; 603fd4e5da5Sopenharmony_ci bool IsFloatScalarType(uint32_t id) const; 604fd4e5da5Sopenharmony_ci bool IsFloatVectorType(uint32_t id) const; 605fd4e5da5Sopenharmony_ci bool IsFloatScalarOrVectorType(uint32_t id) const; 606fd4e5da5Sopenharmony_ci bool IsFloatMatrixType(uint32_t id) const; 607fd4e5da5Sopenharmony_ci bool IsIntScalarType(uint32_t id) const; 608fd4e5da5Sopenharmony_ci bool IsIntVectorType(uint32_t id) const; 609fd4e5da5Sopenharmony_ci bool IsIntScalarOrVectorType(uint32_t id) const; 610fd4e5da5Sopenharmony_ci bool IsUnsignedIntScalarType(uint32_t id) const; 611fd4e5da5Sopenharmony_ci bool IsUnsignedIntVectorType(uint32_t id) const; 612fd4e5da5Sopenharmony_ci bool IsUnsignedIntScalarOrVectorType(uint32_t id) const; 613fd4e5da5Sopenharmony_ci bool IsSignedIntScalarType(uint32_t id) const; 614fd4e5da5Sopenharmony_ci bool IsSignedIntVectorType(uint32_t id) const; 615fd4e5da5Sopenharmony_ci bool IsBoolScalarType(uint32_t id) const; 616fd4e5da5Sopenharmony_ci bool IsBoolVectorType(uint32_t id) const; 617fd4e5da5Sopenharmony_ci bool IsBoolScalarOrVectorType(uint32_t id) const; 618fd4e5da5Sopenharmony_ci bool IsPointerType(uint32_t id) const; 619fd4e5da5Sopenharmony_ci bool IsAccelerationStructureType(uint32_t id) const; 620fd4e5da5Sopenharmony_ci bool IsCooperativeMatrixType(uint32_t id) const; 621fd4e5da5Sopenharmony_ci bool IsCooperativeMatrixNVType(uint32_t id) const; 622fd4e5da5Sopenharmony_ci bool IsCooperativeMatrixKHRType(uint32_t id) const; 623fd4e5da5Sopenharmony_ci bool IsCooperativeMatrixAType(uint32_t id) const; 624fd4e5da5Sopenharmony_ci bool IsCooperativeMatrixBType(uint32_t id) const; 625fd4e5da5Sopenharmony_ci bool IsCooperativeMatrixAccType(uint32_t id) const; 626fd4e5da5Sopenharmony_ci bool IsFloatCooperativeMatrixType(uint32_t id) const; 627fd4e5da5Sopenharmony_ci bool IsIntCooperativeMatrixType(uint32_t id) const; 628fd4e5da5Sopenharmony_ci bool IsUnsignedIntCooperativeMatrixType(uint32_t id) const; 629fd4e5da5Sopenharmony_ci bool IsUnsigned64BitHandle(uint32_t id) const; 630fd4e5da5Sopenharmony_ci 631fd4e5da5Sopenharmony_ci // Returns true if |id| is a type id that contains |type| (or integer or 632fd4e5da5Sopenharmony_ci // floating point type) of |width| bits. 633fd4e5da5Sopenharmony_ci bool ContainsSizedIntOrFloatType(uint32_t id, spv::Op type, 634fd4e5da5Sopenharmony_ci uint32_t width) const; 635fd4e5da5Sopenharmony_ci // Returns true if |id| is a type id that contains a 8- or 16-bit int or 636fd4e5da5Sopenharmony_ci // 16-bit float that is not generally enabled for use. 637fd4e5da5Sopenharmony_ci bool ContainsLimitedUseIntOrFloatType(uint32_t id) const; 638fd4e5da5Sopenharmony_ci 639fd4e5da5Sopenharmony_ci // Returns true if |id| is a type that contains a runtime-sized array. 640fd4e5da5Sopenharmony_ci // Does not consider a pointers as contains the array. 641fd4e5da5Sopenharmony_ci bool ContainsRuntimeArray(uint32_t id) const; 642fd4e5da5Sopenharmony_ci 643fd4e5da5Sopenharmony_ci // Generic type traversal. 644fd4e5da5Sopenharmony_ci // Only traverse pointers and functions if |traverse_all_types| is true. 645fd4e5da5Sopenharmony_ci // Recursively tests |f| against the type hierarchy headed by |id|. 646fd4e5da5Sopenharmony_ci bool ContainsType(uint32_t id, 647fd4e5da5Sopenharmony_ci const std::function<bool(const Instruction*)>& f, 648fd4e5da5Sopenharmony_ci bool traverse_all_types = true) const; 649fd4e5da5Sopenharmony_ci 650fd4e5da5Sopenharmony_ci // Gets value from OpConstant and OpSpecConstant as uint64. 651fd4e5da5Sopenharmony_ci // Returns false on failure (no instruction, wrong instruction, not int). 652fd4e5da5Sopenharmony_ci bool GetConstantValUint64(uint32_t id, uint64_t* val) const; 653fd4e5da5Sopenharmony_ci 654fd4e5da5Sopenharmony_ci // Returns type_id if id has type or zero otherwise. 655fd4e5da5Sopenharmony_ci uint32_t GetTypeId(uint32_t id) const; 656fd4e5da5Sopenharmony_ci 657fd4e5da5Sopenharmony_ci // Returns opcode of the instruction which issued the id or OpNop if the 658fd4e5da5Sopenharmony_ci // instruction is not registered. 659fd4e5da5Sopenharmony_ci spv::Op GetIdOpcode(uint32_t id) const; 660fd4e5da5Sopenharmony_ci 661fd4e5da5Sopenharmony_ci // Returns type_id for given id operand if it has a type or zero otherwise. 662fd4e5da5Sopenharmony_ci // |operand_index| is expected to be pointing towards an operand which is an 663fd4e5da5Sopenharmony_ci // id. 664fd4e5da5Sopenharmony_ci uint32_t GetOperandTypeId(const Instruction* inst, 665fd4e5da5Sopenharmony_ci size_t operand_index) const; 666fd4e5da5Sopenharmony_ci 667fd4e5da5Sopenharmony_ci // Provides information on pointer type. Returns false iff not pointer type. 668fd4e5da5Sopenharmony_ci bool GetPointerTypeInfo(uint32_t id, uint32_t* data_type, 669fd4e5da5Sopenharmony_ci spv::StorageClass* storage_class) const; 670fd4e5da5Sopenharmony_ci 671fd4e5da5Sopenharmony_ci // Is the ID the type of a pointer to a uniform block: Block-decorated struct 672fd4e5da5Sopenharmony_ci // in uniform storage class? The result is only valid after internal method 673fd4e5da5Sopenharmony_ci // CheckDecorationsOfBuffers has been called. 674fd4e5da5Sopenharmony_ci bool IsPointerToUniformBlock(uint32_t type_id) const { 675fd4e5da5Sopenharmony_ci return pointer_to_uniform_block_.find(type_id) != 676fd4e5da5Sopenharmony_ci pointer_to_uniform_block_.cend(); 677fd4e5da5Sopenharmony_ci } 678fd4e5da5Sopenharmony_ci // Save the ID of a pointer to uniform block. 679fd4e5da5Sopenharmony_ci void RegisterPointerToUniformBlock(uint32_t type_id) { 680fd4e5da5Sopenharmony_ci pointer_to_uniform_block_.insert(type_id); 681fd4e5da5Sopenharmony_ci } 682fd4e5da5Sopenharmony_ci // Is the ID the type of a struct used as a uniform block? 683fd4e5da5Sopenharmony_ci // The result is only valid after internal method CheckDecorationsOfBuffers 684fd4e5da5Sopenharmony_ci // has been called. 685fd4e5da5Sopenharmony_ci bool IsStructForUniformBlock(uint32_t type_id) const { 686fd4e5da5Sopenharmony_ci return struct_for_uniform_block_.find(type_id) != 687fd4e5da5Sopenharmony_ci struct_for_uniform_block_.cend(); 688fd4e5da5Sopenharmony_ci } 689fd4e5da5Sopenharmony_ci // Save the ID of a struct of a uniform block. 690fd4e5da5Sopenharmony_ci void RegisterStructForUniformBlock(uint32_t type_id) { 691fd4e5da5Sopenharmony_ci struct_for_uniform_block_.insert(type_id); 692fd4e5da5Sopenharmony_ci } 693fd4e5da5Sopenharmony_ci // Is the ID the type of a pointer to a storage buffer: BufferBlock-decorated 694fd4e5da5Sopenharmony_ci // struct in uniform storage class, or Block-decorated struct in StorageBuffer 695fd4e5da5Sopenharmony_ci // storage class? The result is only valid after internal method 696fd4e5da5Sopenharmony_ci // CheckDecorationsOfBuffers has been called. 697fd4e5da5Sopenharmony_ci bool IsPointerToStorageBuffer(uint32_t type_id) const { 698fd4e5da5Sopenharmony_ci return pointer_to_storage_buffer_.find(type_id) != 699fd4e5da5Sopenharmony_ci pointer_to_storage_buffer_.cend(); 700fd4e5da5Sopenharmony_ci } 701fd4e5da5Sopenharmony_ci // Save the ID of a pointer to a storage buffer. 702fd4e5da5Sopenharmony_ci void RegisterPointerToStorageBuffer(uint32_t type_id) { 703fd4e5da5Sopenharmony_ci pointer_to_storage_buffer_.insert(type_id); 704fd4e5da5Sopenharmony_ci } 705fd4e5da5Sopenharmony_ci // Is the ID the type of a struct for storage buffer? 706fd4e5da5Sopenharmony_ci // The result is only valid after internal method CheckDecorationsOfBuffers 707fd4e5da5Sopenharmony_ci // has been called. 708fd4e5da5Sopenharmony_ci bool IsStructForStorageBuffer(uint32_t type_id) const { 709fd4e5da5Sopenharmony_ci return struct_for_storage_buffer_.find(type_id) != 710fd4e5da5Sopenharmony_ci struct_for_storage_buffer_.cend(); 711fd4e5da5Sopenharmony_ci } 712fd4e5da5Sopenharmony_ci // Save the ID of a struct of a storage buffer. 713fd4e5da5Sopenharmony_ci void RegisterStructForStorageBuffer(uint32_t type_id) { 714fd4e5da5Sopenharmony_ci struct_for_storage_buffer_.insert(type_id); 715fd4e5da5Sopenharmony_ci } 716fd4e5da5Sopenharmony_ci 717fd4e5da5Sopenharmony_ci // Is the ID the type of a pointer to a storage image? That is, the pointee 718fd4e5da5Sopenharmony_ci // type is an image type which is known to not use a sampler. 719fd4e5da5Sopenharmony_ci bool IsPointerToStorageImage(uint32_t type_id) const { 720fd4e5da5Sopenharmony_ci return pointer_to_storage_image_.find(type_id) != 721fd4e5da5Sopenharmony_ci pointer_to_storage_image_.cend(); 722fd4e5da5Sopenharmony_ci } 723fd4e5da5Sopenharmony_ci // Save the ID of a pointer to a storage image. 724fd4e5da5Sopenharmony_ci void RegisterPointerToStorageImage(uint32_t type_id) { 725fd4e5da5Sopenharmony_ci pointer_to_storage_image_.insert(type_id); 726fd4e5da5Sopenharmony_ci } 727fd4e5da5Sopenharmony_ci 728fd4e5da5Sopenharmony_ci // Tries to evaluate a 32-bit signed or unsigned scalar integer constant. 729fd4e5da5Sopenharmony_ci // Returns tuple <is_int32, is_const_int32, value>. 730fd4e5da5Sopenharmony_ci // OpSpecConstant* return |is_const_int32| as false since their values cannot 731fd4e5da5Sopenharmony_ci // be relied upon during validation. 732fd4e5da5Sopenharmony_ci std::tuple<bool, bool, uint32_t> EvalInt32IfConst(uint32_t id) const; 733fd4e5da5Sopenharmony_ci 734fd4e5da5Sopenharmony_ci // Returns the disassembly string for the given instruction. 735fd4e5da5Sopenharmony_ci std::string Disassemble(const Instruction& inst) const; 736fd4e5da5Sopenharmony_ci 737fd4e5da5Sopenharmony_ci // Returns the disassembly string for the given instruction. 738fd4e5da5Sopenharmony_ci std::string Disassemble(const uint32_t* words, uint16_t num_words) const; 739fd4e5da5Sopenharmony_ci 740fd4e5da5Sopenharmony_ci // Returns the string name for |decoration|. 741fd4e5da5Sopenharmony_ci std::string SpvDecorationString(uint32_t decoration) { 742fd4e5da5Sopenharmony_ci spv_operand_desc desc = nullptr; 743fd4e5da5Sopenharmony_ci if (grammar_.lookupOperand(SPV_OPERAND_TYPE_DECORATION, decoration, 744fd4e5da5Sopenharmony_ci &desc) != SPV_SUCCESS) { 745fd4e5da5Sopenharmony_ci return std::string("Unknown"); 746fd4e5da5Sopenharmony_ci } 747fd4e5da5Sopenharmony_ci return std::string(desc->name); 748fd4e5da5Sopenharmony_ci } 749fd4e5da5Sopenharmony_ci std::string SpvDecorationString(spv::Decoration decoration) { 750fd4e5da5Sopenharmony_ci return SpvDecorationString(uint32_t(decoration)); 751fd4e5da5Sopenharmony_ci } 752fd4e5da5Sopenharmony_ci 753fd4e5da5Sopenharmony_ci // Returns whether type m1 and type m2 are cooperative matrices with 754fd4e5da5Sopenharmony_ci // the same "shape" (matching scope, rows, cols). If any are specialization 755fd4e5da5Sopenharmony_ci // constants, we assume they can match because we can't prove they don't. 756fd4e5da5Sopenharmony_ci spv_result_t CooperativeMatrixShapesMatch(const Instruction* inst, 757fd4e5da5Sopenharmony_ci uint32_t m1, uint32_t m2); 758fd4e5da5Sopenharmony_ci 759fd4e5da5Sopenharmony_ci // Returns true if |lhs| and |rhs| logically match and, if the decorations of 760fd4e5da5Sopenharmony_ci // |rhs| are a subset of |lhs|. 761fd4e5da5Sopenharmony_ci // 762fd4e5da5Sopenharmony_ci // 1. Must both be either OpTypeArray or OpTypeStruct 763fd4e5da5Sopenharmony_ci // 2. If OpTypeArray, then 764fd4e5da5Sopenharmony_ci // * Length must be the same 765fd4e5da5Sopenharmony_ci // * Element type must match or logically match 766fd4e5da5Sopenharmony_ci // 3. If OpTypeStruct, then 767fd4e5da5Sopenharmony_ci // * Both have same number of elements 768fd4e5da5Sopenharmony_ci // * Element N for both structs must match or logically match 769fd4e5da5Sopenharmony_ci // 770fd4e5da5Sopenharmony_ci // If |check_decorations| is false, then the decorations are not checked. 771fd4e5da5Sopenharmony_ci bool LogicallyMatch(const Instruction* lhs, const Instruction* rhs, 772fd4e5da5Sopenharmony_ci bool check_decorations); 773fd4e5da5Sopenharmony_ci 774fd4e5da5Sopenharmony_ci // Traces |inst| to find a single base pointer. Returns the base pointer. 775fd4e5da5Sopenharmony_ci // Will trace through the following instructions: 776fd4e5da5Sopenharmony_ci // * OpAccessChain 777fd4e5da5Sopenharmony_ci // * OpInBoundsAccessChain 778fd4e5da5Sopenharmony_ci // * OpPtrAccessChain 779fd4e5da5Sopenharmony_ci // * OpInBoundsPtrAccessChain 780fd4e5da5Sopenharmony_ci // * OpCopyObject 781fd4e5da5Sopenharmony_ci const Instruction* TracePointer(const Instruction* inst) const; 782fd4e5da5Sopenharmony_ci 783fd4e5da5Sopenharmony_ci // Validates the storage class for the target environment. 784fd4e5da5Sopenharmony_ci bool IsValidStorageClass(spv::StorageClass storage_class) const; 785fd4e5da5Sopenharmony_ci 786fd4e5da5Sopenharmony_ci // Takes a Vulkan Valid Usage ID (VUID) as |id| and optional |reference| and 787fd4e5da5Sopenharmony_ci // will return a non-empty string only if ID is known and targeting Vulkan. 788fd4e5da5Sopenharmony_ci // VUIDs are found in the Vulkan-Docs repo in the form "[[VUID-ref-ref-id]]" 789fd4e5da5Sopenharmony_ci // where "id" is always an 5 char long number (with zeros padding) and matches 790fd4e5da5Sopenharmony_ci // to |id|. |reference| is used if there is a "common validity" and the VUID 791fd4e5da5Sopenharmony_ci // shares the same |id| value. 792fd4e5da5Sopenharmony_ci // 793fd4e5da5Sopenharmony_ci // More details about Vulkan validation can be found in Vulkan Guide: 794fd4e5da5Sopenharmony_ci // https://github.com/KhronosGroup/Vulkan-Guide/blob/master/chapters/validation_overview.md 795fd4e5da5Sopenharmony_ci std::string VkErrorID(uint32_t id, const char* reference = nullptr) const; 796fd4e5da5Sopenharmony_ci 797fd4e5da5Sopenharmony_ci // Testing method to allow setting the current layout section. 798fd4e5da5Sopenharmony_ci void SetCurrentLayoutSectionForTesting(ModuleLayoutSection section) { 799fd4e5da5Sopenharmony_ci current_layout_section_ = section; 800fd4e5da5Sopenharmony_ci } 801fd4e5da5Sopenharmony_ci 802fd4e5da5Sopenharmony_ci // Check if instruction 'id' is a consumer of a texture decorated 803fd4e5da5Sopenharmony_ci // with a QCOM image processing decoration 804fd4e5da5Sopenharmony_ci bool IsQCOMImageProcessingTextureConsumer(uint32_t id) { 805fd4e5da5Sopenharmony_ci return qcom_image_processing_consumers_.find(id) != 806fd4e5da5Sopenharmony_ci qcom_image_processing_consumers_.end(); 807fd4e5da5Sopenharmony_ci } 808fd4e5da5Sopenharmony_ci 809fd4e5da5Sopenharmony_ci private: 810fd4e5da5Sopenharmony_ci ValidationState_t(const ValidationState_t&); 811fd4e5da5Sopenharmony_ci 812fd4e5da5Sopenharmony_ci const spv_const_context context_; 813fd4e5da5Sopenharmony_ci 814fd4e5da5Sopenharmony_ci /// Stores the Validator command line options. Must be a valid options object. 815fd4e5da5Sopenharmony_ci const spv_const_validator_options options_; 816fd4e5da5Sopenharmony_ci 817fd4e5da5Sopenharmony_ci /// The SPIR-V binary module we're validating. 818fd4e5da5Sopenharmony_ci const uint32_t* words_; 819fd4e5da5Sopenharmony_ci const size_t num_words_; 820fd4e5da5Sopenharmony_ci 821fd4e5da5Sopenharmony_ci /// The generator of the SPIR-V. 822fd4e5da5Sopenharmony_ci uint32_t generator_ = 0; 823fd4e5da5Sopenharmony_ci 824fd4e5da5Sopenharmony_ci /// The version of the SPIR-V. 825fd4e5da5Sopenharmony_ci uint32_t version_ = 0; 826fd4e5da5Sopenharmony_ci 827fd4e5da5Sopenharmony_ci /// The total number of instructions in the binary. 828fd4e5da5Sopenharmony_ci size_t total_instructions_ = 0; 829fd4e5da5Sopenharmony_ci /// The total number of functions in the binary. 830fd4e5da5Sopenharmony_ci size_t total_functions_ = 0; 831fd4e5da5Sopenharmony_ci 832fd4e5da5Sopenharmony_ci /// IDs which have been forward declared but have not been defined 833fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> unresolved_forward_ids_; 834fd4e5da5Sopenharmony_ci 835fd4e5da5Sopenharmony_ci /// IDs that have been declared as forward pointers. 836fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> forward_pointer_ids_; 837fd4e5da5Sopenharmony_ci 838fd4e5da5Sopenharmony_ci /// Stores a vector of instructions that use the result of a given 839fd4e5da5Sopenharmony_ci /// OpSampledImage instruction. 840fd4e5da5Sopenharmony_ci std::unordered_map<uint32_t, std::vector<Instruction*>> 841fd4e5da5Sopenharmony_ci sampled_image_consumers_; 842fd4e5da5Sopenharmony_ci 843fd4e5da5Sopenharmony_ci /// Stores load instructions that load textures used 844fd4e5da5Sopenharmony_ci // in QCOM image processing functions 845fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> qcom_image_processing_consumers_; 846fd4e5da5Sopenharmony_ci 847fd4e5da5Sopenharmony_ci /// A map of operand IDs and their names defined by the OpName instruction 848fd4e5da5Sopenharmony_ci std::unordered_map<uint32_t, std::string> operand_names_; 849fd4e5da5Sopenharmony_ci 850fd4e5da5Sopenharmony_ci /// The section of the code being processed 851fd4e5da5Sopenharmony_ci ModuleLayoutSection current_layout_section_; 852fd4e5da5Sopenharmony_ci 853fd4e5da5Sopenharmony_ci /// A list of functions in the module. 854fd4e5da5Sopenharmony_ci /// Pointers to objects in this container are guaranteed to be stable and 855fd4e5da5Sopenharmony_ci /// valid until the end of lifetime of the validation state. 856fd4e5da5Sopenharmony_ci std::vector<Function> module_functions_; 857fd4e5da5Sopenharmony_ci 858fd4e5da5Sopenharmony_ci /// Capabilities declared in the module 859fd4e5da5Sopenharmony_ci CapabilitySet module_capabilities_; 860fd4e5da5Sopenharmony_ci 861fd4e5da5Sopenharmony_ci /// Extensions declared in the module 862fd4e5da5Sopenharmony_ci ExtensionSet module_extensions_; 863fd4e5da5Sopenharmony_ci 864fd4e5da5Sopenharmony_ci /// List of all instructions in the order they appear in the binary 865fd4e5da5Sopenharmony_ci std::vector<Instruction> ordered_instructions_; 866fd4e5da5Sopenharmony_ci 867fd4e5da5Sopenharmony_ci /// Instructions that can be referenced by Ids 868fd4e5da5Sopenharmony_ci std::unordered_map<uint32_t, Instruction*> all_definitions_; 869fd4e5da5Sopenharmony_ci 870fd4e5da5Sopenharmony_ci /// IDs that are entry points, ie, arguments to OpEntryPoint. 871fd4e5da5Sopenharmony_ci std::vector<uint32_t> entry_points_; 872fd4e5da5Sopenharmony_ci 873fd4e5da5Sopenharmony_ci /// Maps an entry point id to its descriptions. 874fd4e5da5Sopenharmony_ci std::unordered_map<uint32_t, std::vector<EntryPointDescription>> 875fd4e5da5Sopenharmony_ci entry_point_descriptions_; 876fd4e5da5Sopenharmony_ci 877fd4e5da5Sopenharmony_ci /// IDs that are entry points, ie, arguments to OpEntryPoint, and root a call 878fd4e5da5Sopenharmony_ci /// graph that recurses. 879fd4e5da5Sopenharmony_ci std::set<uint32_t> recursive_entry_points_; 880fd4e5da5Sopenharmony_ci 881fd4e5da5Sopenharmony_ci /// Functions IDs that are target of OpFunctionCall. 882fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> function_call_targets_; 883fd4e5da5Sopenharmony_ci 884fd4e5da5Sopenharmony_ci /// ID Bound from the Header 885fd4e5da5Sopenharmony_ci uint32_t id_bound_; 886fd4e5da5Sopenharmony_ci 887fd4e5da5Sopenharmony_ci /// Set of Global Variable IDs (Storage Class other than 'Function') 888fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> global_vars_; 889fd4e5da5Sopenharmony_ci 890fd4e5da5Sopenharmony_ci /// Set of Local Variable IDs ('Function' Storage Class) 891fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> local_vars_; 892fd4e5da5Sopenharmony_ci 893fd4e5da5Sopenharmony_ci /// Set of struct types that have members with a BuiltIn decoration. 894fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> builtin_structs_; 895fd4e5da5Sopenharmony_ci 896fd4e5da5Sopenharmony_ci /// Structure Nesting Depth 897fd4e5da5Sopenharmony_ci std::unordered_map<uint32_t, uint32_t> struct_nesting_depth_; 898fd4e5da5Sopenharmony_ci 899fd4e5da5Sopenharmony_ci /// Structure has nested blockorbufferblock struct 900fd4e5da5Sopenharmony_ci std::unordered_map<uint32_t, bool> 901fd4e5da5Sopenharmony_ci struct_has_nested_blockorbufferblock_struct_; 902fd4e5da5Sopenharmony_ci 903fd4e5da5Sopenharmony_ci /// Stores the list of decorations for a given <id> 904fd4e5da5Sopenharmony_ci std::map<uint32_t, std::set<Decoration>> id_decorations_; 905fd4e5da5Sopenharmony_ci 906fd4e5da5Sopenharmony_ci /// Stores type declarations which need to be unique (i.e. non-aggregates), 907fd4e5da5Sopenharmony_ci /// in the form [opcode, operand words], result_id is not stored. 908fd4e5da5Sopenharmony_ci /// Using ordered set to avoid the need for a vector hash function. 909fd4e5da5Sopenharmony_ci /// The size of this container is expected not to exceed double-digits. 910fd4e5da5Sopenharmony_ci std::set<std::vector<uint32_t>> unique_type_declarations_; 911fd4e5da5Sopenharmony_ci 912fd4e5da5Sopenharmony_ci AssemblyGrammar grammar_; 913fd4e5da5Sopenharmony_ci 914fd4e5da5Sopenharmony_ci spv::AddressingModel addressing_model_; 915fd4e5da5Sopenharmony_ci spv::MemoryModel memory_model_; 916fd4e5da5Sopenharmony_ci // pointer size derived from addressing model. Assumes all storage classes 917fd4e5da5Sopenharmony_ci // have the same pointer size (for physical pointer types). 918fd4e5da5Sopenharmony_ci uint32_t pointer_size_and_alignment_; 919fd4e5da5Sopenharmony_ci 920fd4e5da5Sopenharmony_ci /// bit width of sampler/image type variables. Valid values are 32 and 64 921fd4e5da5Sopenharmony_ci uint32_t sampler_image_addressing_mode_; 922fd4e5da5Sopenharmony_ci 923fd4e5da5Sopenharmony_ci /// NOTE: See correspoding getter functions 924fd4e5da5Sopenharmony_ci bool in_function_; 925fd4e5da5Sopenharmony_ci 926fd4e5da5Sopenharmony_ci /// The state of optional features. These are determined by capabilities 927fd4e5da5Sopenharmony_ci /// declared by the module and the environment. 928fd4e5da5Sopenharmony_ci Feature features_; 929fd4e5da5Sopenharmony_ci 930fd4e5da5Sopenharmony_ci /// Maps function ids to function stat objects. 931fd4e5da5Sopenharmony_ci std::unordered_map<uint32_t, Function*> id_to_function_; 932fd4e5da5Sopenharmony_ci 933fd4e5da5Sopenharmony_ci /// Mapping entry point -> execution models. It is presumed that the same 934fd4e5da5Sopenharmony_ci /// function could theoretically be used as 'main' by multiple OpEntryPoint 935fd4e5da5Sopenharmony_ci /// instructions. 936fd4e5da5Sopenharmony_ci std::unordered_map<uint32_t, std::set<spv::ExecutionModel>> 937fd4e5da5Sopenharmony_ci entry_point_to_execution_models_; 938fd4e5da5Sopenharmony_ci 939fd4e5da5Sopenharmony_ci /// Mapping entry point -> execution modes. 940fd4e5da5Sopenharmony_ci std::unordered_map<uint32_t, std::set<spv::ExecutionMode>> 941fd4e5da5Sopenharmony_ci entry_point_to_execution_modes_; 942fd4e5da5Sopenharmony_ci 943fd4e5da5Sopenharmony_ci /// Mapping function -> array of entry points inside this 944fd4e5da5Sopenharmony_ci /// module which can (indirectly) call the function. 945fd4e5da5Sopenharmony_ci std::unordered_map<uint32_t, std::vector<uint32_t>> function_to_entry_points_; 946fd4e5da5Sopenharmony_ci const std::vector<uint32_t> empty_ids_; 947fd4e5da5Sopenharmony_ci 948fd4e5da5Sopenharmony_ci // The IDs of types of pointers to Block-decorated structs in Uniform storage 949fd4e5da5Sopenharmony_ci // class. This is populated at the start of ValidateDecorations. 950fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> pointer_to_uniform_block_; 951fd4e5da5Sopenharmony_ci // The IDs of struct types for uniform blocks. 952fd4e5da5Sopenharmony_ci // This is populated at the start of ValidateDecorations. 953fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> struct_for_uniform_block_; 954fd4e5da5Sopenharmony_ci // The IDs of types of pointers to BufferBlock-decorated structs in Uniform 955fd4e5da5Sopenharmony_ci // storage class, or Block-decorated structs in StorageBuffer storage class. 956fd4e5da5Sopenharmony_ci // This is populated at the start of ValidateDecorations. 957fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> pointer_to_storage_buffer_; 958fd4e5da5Sopenharmony_ci // The IDs of struct types for storage buffers. 959fd4e5da5Sopenharmony_ci // This is populated at the start of ValidateDecorations. 960fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> struct_for_storage_buffer_; 961fd4e5da5Sopenharmony_ci // The IDs of types of pointers to storage images. This is populated in the 962fd4e5da5Sopenharmony_ci // TypePass. 963fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> pointer_to_storage_image_; 964fd4e5da5Sopenharmony_ci 965fd4e5da5Sopenharmony_ci /// Maps ids to friendly names. 966fd4e5da5Sopenharmony_ci std::unique_ptr<spvtools::FriendlyNameMapper> friendly_mapper_; 967fd4e5da5Sopenharmony_ci spvtools::NameMapper name_mapper_; 968fd4e5da5Sopenharmony_ci 969fd4e5da5Sopenharmony_ci /// Variables used to reduce the number of diagnostic messages. 970fd4e5da5Sopenharmony_ci uint32_t num_of_warnings_; 971fd4e5da5Sopenharmony_ci uint32_t max_num_of_warnings_; 972fd4e5da5Sopenharmony_ci}; 973fd4e5da5Sopenharmony_ci 974fd4e5da5Sopenharmony_ci} // namespace val 975fd4e5da5Sopenharmony_ci} // namespace spvtools 976fd4e5da5Sopenharmony_ci 977fd4e5da5Sopenharmony_ci#endif // SOURCE_VAL_VALIDATION_STATE_H_ 978