/src/spirv-cross/spirv_parser.hpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2018-2021 Arm Limited |
3 | | * SPDX-License-Identifier: Apache-2.0 OR MIT |
4 | | * |
5 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | | * you may not use this file except in compliance with the License. |
7 | | * You may obtain a copy of the License at |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | */ |
17 | | |
18 | | /* |
19 | | * At your option, you may choose to accept this material under either: |
20 | | * 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or |
21 | | * 2. The MIT License, found at <http://opensource.org/licenses/MIT>. |
22 | | */ |
23 | | |
24 | | #ifndef SPIRV_CROSS_PARSER_HPP |
25 | | #define SPIRV_CROSS_PARSER_HPP |
26 | | |
27 | | #include "spirv_cross_parsed_ir.hpp" |
28 | | #include <stdint.h> |
29 | | |
30 | | namespace SPIRV_CROSS_NAMESPACE |
31 | | { |
32 | | class Parser |
33 | | { |
34 | | public: |
35 | | Parser(const uint32_t *spirv_data, size_t word_count); |
36 | | Parser(std::vector<uint32_t> spirv); |
37 | | |
38 | | void parse(); |
39 | | |
40 | | ParsedIR &get_parsed_ir() |
41 | 600 | { |
42 | 600 | return ir; |
43 | 600 | } |
44 | | |
45 | | private: |
46 | | ParsedIR ir; |
47 | | SPIRFunction *current_function = nullptr; |
48 | | SPIRBlock *current_block = nullptr; |
49 | | // For workarounds. |
50 | | bool ignore_trailing_block_opcodes = false; |
51 | | |
52 | | void parse(const Instruction &instr); |
53 | | const uint32_t *stream(const Instruction &instr) const; |
54 | | |
55 | | template <typename T, typename... P> |
56 | | T &set(uint32_t id, P &&... args) |
57 | 57.4k | { |
58 | 57.4k | ir.add_typed_id(static_cast<Types>(T::type), id); |
59 | 57.4k | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); |
60 | 57.4k | var.self = id; |
61 | 57.4k | return var; |
62 | 57.4k | } spirv_cross::SPIRString& spirv_cross::Parser::set<spirv_cross::SPIRString, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(unsigned int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&) Line | Count | Source | 57 | 886 | { | 58 | 886 | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 886 | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 886 | var.self = id; | 61 | 886 | return var; | 62 | 886 | } |
spirv_cross::SPIRUndef& spirv_cross::Parser::set<spirv_cross::SPIRUndef, unsigned int&>(unsigned int, unsigned int&) Line | Count | Source | 57 | 1.81k | { | 58 | 1.81k | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 1.81k | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 1.81k | var.self = id; | 61 | 1.81k | return var; | 62 | 1.81k | } |
spirv_cross::SPIRExtension& spirv_cross::Parser::set<spirv_cross::SPIRExtension, spirv_cross::SPIRExtension::Extension&>(unsigned int, spirv_cross::SPIRExtension::Extension&) Line | Count | Source | 57 | 508 | { | 58 | 508 | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 508 | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 508 | var.self = id; | 61 | 508 | return var; | 62 | 508 | } |
spirv_cross::SPIRType& spirv_cross::Parser::set<spirv_cross::SPIRType, spv::Op&>(unsigned int, spv::Op&) Line | Count | Source | 57 | 18.7k | { | 58 | 18.7k | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 18.7k | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 18.7k | var.self = id; | 61 | 18.7k | return var; | 62 | 18.7k | } |
spirv_cross::SPIRType& spirv_cross::Parser::set<spirv_cross::SPIRType, spirv_cross::SPIRType&>(unsigned int, spirv_cross::SPIRType&) Line | Count | Source | 57 | 3.45k | { | 58 | 3.45k | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 3.45k | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 3.45k | var.self = id; | 61 | 3.45k | return var; | 62 | 3.45k | } |
spirv_cross::SPIRFunctionPrototype& spirv_cross::Parser::set<spirv_cross::SPIRFunctionPrototype, unsigned int&>(unsigned int, unsigned int&) Line | Count | Source | 57 | 5.83k | { | 58 | 5.83k | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 5.83k | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 5.83k | var.self = id; | 61 | 5.83k | return var; | 62 | 5.83k | } |
spirv_cross::SPIRVariable& spirv_cross::Parser::set<spirv_cross::SPIRVariable, unsigned int&, spv::StorageClass&, unsigned int&>(unsigned int, unsigned int&, spv::StorageClass&, unsigned int&) Line | Count | Source | 57 | 6.43k | { | 58 | 6.43k | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 6.43k | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 6.43k | var.self = id; | 61 | 6.43k | return var; | 62 | 6.43k | } |
spirv_cross::SPIRVariable& spirv_cross::Parser::set<spirv_cross::SPIRVariable, unsigned int&, spv::StorageClass>(unsigned int, unsigned int&, spv::StorageClass&&) Line | Count | Source | 57 | 3.07k | { | 58 | 3.07k | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 3.07k | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 3.07k | var.self = id; | 61 | 3.07k | return var; | 62 | 3.07k | } |
spirv_cross::SPIRConstant& spirv_cross::Parser::set<spirv_cross::SPIRConstant, unsigned int const&, unsigned long, bool>(unsigned int, unsigned int const&, unsigned long&&, bool&&) Line | Count | Source | 57 | 18 | { | 58 | 18 | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 18 | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 18 | var.self = id; | 61 | 18 | return var; | 62 | 18 | } |
spirv_cross::SPIRConstant& spirv_cross::Parser::set<spirv_cross::SPIRConstant, unsigned int const&, unsigned int const&, bool>(unsigned int, unsigned int const&, unsigned int const&, bool&&) Line | Count | Source | 57 | 3.90k | { | 58 | 3.90k | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 3.90k | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 3.90k | var.self = id; | 61 | 3.90k | return var; | 62 | 3.90k | } |
spirv_cross::SPIRConstant& spirv_cross::Parser::set<spirv_cross::SPIRConstant, unsigned int const&, unsigned int, bool>(unsigned int, unsigned int const&, unsigned int&&, bool&&) Line | Count | Source | 57 | 613 | { | 58 | 613 | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 613 | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 613 | var.self = id; | 61 | 613 | return var; | 62 | 613 | } |
spirv_cross::SPIRConstant& spirv_cross::Parser::set<spirv_cross::SPIRConstant, unsigned int&, unsigned int const*, unsigned int, bool>(unsigned int, unsigned int&, unsigned int const*&&, unsigned int&&, bool&&) Line | Count | Source | 57 | 409 | { | 58 | 409 | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 409 | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 409 | var.self = id; | 61 | 409 | return var; | 62 | 409 | } |
spirv_cross::SPIRConstant& spirv_cross::Parser::set<spirv_cross::SPIRConstant, unsigned int&, spirv_cross::SPIRConstant const* (&) [4], unsigned int&, bool>(unsigned int, unsigned int&, spirv_cross::SPIRConstant const* (&) [4], unsigned int&, bool&&) Line | Count | Source | 57 | 669 | { | 58 | 669 | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 669 | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 669 | var.self = id; | 61 | 669 | return var; | 62 | 669 | } |
spirv_cross::SPIRFunction& spirv_cross::Parser::set<spirv_cross::SPIRFunction, unsigned int&, unsigned int&>(unsigned int, unsigned int&, unsigned int&) Line | Count | Source | 57 | 450 | { | 58 | 450 | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 450 | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 450 | var.self = id; | 61 | 450 | return var; | 62 | 450 | } |
spirv_cross::SPIRBlock& spirv_cross::Parser::set<spirv_cross::SPIRBlock>(unsigned int) Line | Count | Source | 57 | 9.80k | { | 58 | 9.80k | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 9.80k | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 9.80k | var.self = id; | 61 | 9.80k | return var; | 62 | 9.80k | } |
spirv_cross::SPIRType& spirv_cross::Parser::set<spirv_cross::SPIRType, spv::Op>(unsigned int, spv::Op&&) Line | Count | Source | 57 | 28 | { | 58 | 28 | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 28 | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 28 | var.self = id; | 61 | 28 | return var; | 62 | 28 | } |
spirv_cross::SPIRConstant& spirv_cross::Parser::set<spirv_cross::SPIRConstant, unsigned int&>(unsigned int, unsigned int&) Line | Count | Source | 57 | 28 | { | 58 | 28 | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 28 | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 28 | var.self = id; | 61 | 28 | return var; | 62 | 28 | } |
spirv_cross::SPIRConstantOp& spirv_cross::Parser::set<spirv_cross::SPIRConstantOp, unsigned int&, spv::Op&, unsigned int const*, unsigned int>(unsigned int, unsigned int&, spv::Op&, unsigned int const*&&, unsigned int&&) Line | Count | Source | 57 | 791 | { | 58 | 791 | ir.add_typed_id(static_cast<Types>(T::type), id); | 59 | 791 | auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); | 60 | 791 | var.self = id; | 61 | 791 | return var; | 62 | 791 | } |
|
63 | | |
64 | | template <typename T> |
65 | | T &get(uint32_t id) |
66 | 41.3k | { |
67 | 41.3k | return variant_get<T>(ir.ids[id]); |
68 | 41.3k | } spirv_cross::SPIRType& spirv_cross::Parser::get<spirv_cross::SPIRType>(unsigned int) Line | Count | Source | 66 | 38.9k | { | 67 | 38.9k | return variant_get<T>(ir.ids[id]); | 68 | 38.9k | } |
Unexecuted instantiation: spirv_cross::SPIRConstantOp& spirv_cross::Parser::get<spirv_cross::SPIRConstantOp>(unsigned int) Unexecuted instantiation: spirv_cross::SPIRUndef& spirv_cross::Parser::get<spirv_cross::SPIRUndef>(unsigned int) spirv_cross::SPIRConstant& spirv_cross::Parser::get<spirv_cross::SPIRConstant>(unsigned int) Line | Count | Source | 66 | 2.36k | { | 67 | 2.36k | return variant_get<T>(ir.ids[id]); | 68 | 2.36k | } |
|
69 | | |
70 | | template <typename T> |
71 | | T *maybe_get(uint32_t id) |
72 | 36.7k | { |
73 | 36.7k | if (ir.ids[id].get_type() == static_cast<Types>(T::type)) |
74 | 27.1k | return &get<T>(id); |
75 | 9.60k | else |
76 | 9.60k | return nullptr; |
77 | 36.7k | } spirv_cross::SPIRType* spirv_cross::Parser::maybe_get<spirv_cross::SPIRType>(unsigned int) Line | Count | Source | 72 | 32.4k | { | 73 | 32.4k | if (ir.ids[id].get_type() == static_cast<Types>(T::type)) | 74 | 26.7k | return &get<T>(id); | 75 | 5.65k | else | 76 | 5.65k | return nullptr; | 77 | 32.4k | } |
spirv_cross::SPIRConstant* spirv_cross::Parser::maybe_get<spirv_cross::SPIRConstant>(unsigned int) Line | Count | Source | 72 | 383 | { | 73 | 383 | if (ir.ids[id].get_type() == static_cast<Types>(T::type)) | 74 | 383 | return &get<T>(id); | 75 | 0 | else | 76 | 0 | return nullptr; | 77 | 383 | } |
spirv_cross::SPIRConstantOp* spirv_cross::Parser::maybe_get<spirv_cross::SPIRConstantOp>(unsigned int) Line | Count | Source | 72 | 1.97k | { | 73 | 1.97k | if (ir.ids[id].get_type() == static_cast<Types>(T::type)) | 74 | 0 | return &get<T>(id); | 75 | 1.97k | else | 76 | 1.97k | return nullptr; | 77 | 1.97k | } |
spirv_cross::SPIRUndef* spirv_cross::Parser::maybe_get<spirv_cross::SPIRUndef>(unsigned int) Line | Count | Source | 72 | 1.97k | { | 73 | 1.97k | if (ir.ids[id].get_type() == static_cast<Types>(T::type)) | 74 | 0 | return &get<T>(id); | 75 | 1.97k | else | 76 | 1.97k | return nullptr; | 77 | 1.97k | } |
|
78 | | |
79 | | template <typename T> |
80 | | const T &get(uint32_t id) const |
81 | 3.51k | { |
82 | 3.51k | return variant_get<T>(ir.ids[id]); |
83 | 3.51k | } |
84 | | |
85 | | template <typename T> |
86 | | const T *maybe_get(uint32_t id) const |
87 | | { |
88 | | if (ir.ids[id].get_type() == T::type) |
89 | | return &get<T>(id); |
90 | | else |
91 | | return nullptr; |
92 | | } |
93 | | |
94 | | // This must be an ordered data structure so we always pick the same type aliases. |
95 | | SmallVector<uint32_t> global_struct_cache; |
96 | | SmallVector<std::pair<uint32_t, uint32_t>> forward_pointer_fixups; |
97 | | |
98 | | bool types_are_logically_equivalent(const SPIRType &a, const SPIRType &b) const; |
99 | | bool variable_storage_is_aliased(const SPIRVariable &v) const; |
100 | | }; |
101 | | } // namespace SPIRV_CROSS_NAMESPACE |
102 | | |
103 | | #endif |