Home | History | Annotate | Download | only in opt
      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