| 915 | } |
| 916 | |
| 917 | Module::StaticData::StaticData(const Module& module_state, bool parse, StatelessData* stateless_data) { |
| 918 | // If parse is set off, save time because StaticData is never accessed |
| 919 | if (!module_state.valid_spirv || !parse) { |
| 920 | return; |
| 921 | } |
| 922 | |
| 923 | // Parse the words first so we have instruction class objects to use |
| 924 | { |
| 925 | std::vector<uint32_t>::const_iterator it = module_state.words_.cbegin(); |
| 926 | it += 5; // skip first 5 word of header |
| 927 | instructions.reserve(module_state.words_.size() * 4); |
| 928 | while (it != module_state.words_.cend()) { |
| 929 | auto new_insn = instructions.emplace_back(it); |
| 930 | const uint32_t opcode = new_insn.Opcode(); |
| 931 | |
| 932 | // Check for opcodes that would require reparsing of the words |
| 933 | if (opcode == spv::OpGroupDecorate || opcode == spv::OpDecorationGroup || opcode == spv::OpGroupMemberDecorate) { |
| 934 | if (stateless_data) { |
| 935 | assert(stateless_data->has_group_decoration == false); // if assert, spirv-opt didn't flatten it |
| 936 | stateless_data->has_group_decoration = true; |
| 937 | return; // no need to continue parsing |
| 938 | } |
| 939 | } |
| 940 | |
| 941 | it += new_insn.Length(); |
| 942 | } |
| 943 | instructions.shrink_to_fit(); |
| 944 | } |
| 945 | |
| 946 | // We build up a lot of information in an initial pass of the SPIR-V so we can build up data structures around it |
| 947 | ParsedInfo parsed; |
| 948 | |
| 949 | // These have their own object class, but need entire module parsed first |
| 950 | std::vector<const Instruction*> entry_point_instructions; |
| 951 | std::vector<const Instruction*> type_struct_instructions; |
| 952 | std::vector<const Instruction*> image_instructions; |
| 953 | std::vector<const Instruction*> func_call_instructions; |
| 954 | // both OpDecorate and OpMemberDecorate builtin instructions |
| 955 | std::vector<const Instruction*> built_in_decoration_instructions; |
| 956 | |
| 957 | std::vector<uint32_t> store_pointer_ids; |
| 958 | std::vector<uint32_t> load_pointer_ids; |
| 959 | std::vector<uint32_t> atomic_store_pointer_ids; |
| 960 | std::vector<uint32_t> atomic_load_pointer_ids; |
| 961 | |
| 962 | uint32_t last_func_id = 0; |
| 963 | // < Function ID, OpFunctionParameter Ids > |
| 964 | vvl::unordered_map<uint32_t, std::vector<uint32_t>> func_parameter_list; |
| 965 | |
| 966 | // Loop through once and build up the static data |
| 967 | // Also process the entry points |
| 968 | for (const Instruction& insn : instructions) { |
| 969 | // Build definition list |
| 970 | const uint32_t result_id = insn.ResultId(); |
| 971 | if (result_id != 0) { |
| 972 | definitions[result_id] = &insn; |
| 973 | } |
| 974 |
nothing calls this directly
no test coverage detected