1 // Copyright (c) 2016 Google Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef LIBSPIRV_OPT_TYPE_MANAGER_H_ 16 #define LIBSPIRV_OPT_TYPE_MANAGER_H_ 17 18 #include <memory> 19 #include <unordered_map> 20 #include <unordered_set> 21 #include <vector> 22 23 #include "module.h" 24 #include "spirv-tools/libspirv.hpp" 25 #include "types.h" 26 27 namespace spvtools { 28 namespace opt { 29 namespace analysis { 30 31 // A class for managing the SPIR-V type hierarchy. 32 class TypeManager { 33 public: 34 using IdToTypeMap = std::unordered_map<uint32_t, std::unique_ptr<Type>>; 35 36 // Constructs a type manager from the given |module|. All internal messages 37 // will be communicated to the outside via the given message |consumer|. 38 // This instance only keeps a reference to the |consumer|, so the |consumer| 39 // should outlive this instance. 40 TypeManager(const MessageConsumer& consumer, 41 const spvtools::ir::Module& module); 42 43 TypeManager(const TypeManager&) = delete; 44 TypeManager(TypeManager&&) = delete; 45 TypeManager& operator=(const TypeManager&) = delete; 46 TypeManager& operator=(TypeManager&&) = delete; 47 48 // Returns the type for the given type |id|. Returns nullptr if the given |id| 49 // does not define a type. 50 Type* GetType(uint32_t id) const; 51 // Returns the id for the given |type|. Returns 0 if can not find the given 52 // |type|. 53 uint32_t GetId(const Type* type) const; 54 // Returns the number of types hold in this manager. 55 size_t NumTypes() const { return id_to_type_.size(); } 56 // Iterators for all types contained in this manager. 57 IdToTypeMap::const_iterator begin() const { return id_to_type_.cbegin(); } 58 IdToTypeMap::const_iterator end() const { return id_to_type_.cend(); } 59 60 // Returns the forward pointer type at the given |index|. 61 ForwardPointer* GetForwardPointer(uint32_t index) const; 62 // Returns the number of forward pointer types hold in this manager. 63 size_t NumForwardPointers() const { return forward_pointers_.size(); } 64 65 private: 66 using TypeToIdMap = std::unordered_map<const Type*, uint32_t>; 67 using ForwardPointerVector = std::vector<std::unique_ptr<ForwardPointer>>; 68 69 // Analyzes the types and decorations on types in the given |module|. 70 void AnalyzeTypes(const spvtools::ir::Module& module); 71 72 // Creates and returns a type from the given SPIR-V |inst|. Returns nullptr if 73 // the given instruction is not for defining a type. 74 Type* RecordIfTypeDefinition(const spvtools::ir::Instruction& inst); 75 // Attaches the decoration encoded in |inst| to a type. Does nothing if the 76 // given instruction is not a decoration instruction or not decorating a type. 77 void AttachIfTypeDecoration(const spvtools::ir::Instruction& inst); 78 79 const MessageConsumer& consumer_; // Message consumer. 80 IdToTypeMap id_to_type_; // Mapping from ids to their type representations. 81 TypeToIdMap type_to_id_; // Mapping from types to their defining ids. 82 ForwardPointerVector forward_pointers_; // All forward pointer declarations. 83 // All unresolved forward pointer declarations. 84 // Refers the contents in the above vector. 85 std::unordered_set<ForwardPointer*> unresolved_forward_pointers_; 86 }; 87 88 inline TypeManager::TypeManager(const spvtools::MessageConsumer& consumer, 89 const spvtools::ir::Module& module) 90 : consumer_(consumer) { 91 AnalyzeTypes(module); 92 } 93 94 } // namespace analysis 95 } // namespace opt 96 } // namespace spvtools 97 98 #endif // LIBSPIRV_OPT_TYPE_MANAGER_H_ 99