1// Copyright (c) 2017 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 SOURCE_OPT_FEATURE_MANAGER_H_
16#define SOURCE_OPT_FEATURE_MANAGER_H_
17
18#include "source/assembly_grammar.h"
19#include "source/extensions.h"
20#include "source/opt/module.h"
21
22namespace spvtools {
23namespace opt {
24
25// Tracks features enabled by a module. The IRContext has a FeatureManager.
26class FeatureManager {
27 public:
28  // Returns true if |ext| is an enabled extension in the module.
29  bool HasExtension(Extension ext) const { return extensions_.contains(ext); }
30
31  // Returns true if |cap| is an enabled capability in the module.
32  bool HasCapability(spv::Capability cap) const {
33    return capabilities_.contains(cap);
34  }
35
36  // Returns the capabilities the module declares.
37  inline const CapabilitySet& GetCapabilities() const { return capabilities_; }
38
39  // Returns the extensions the module imports.
40  inline const ExtensionSet& GetExtensions() const { return extensions_; }
41
42  uint32_t GetExtInstImportId_GLSLstd450() const {
43    return extinst_importid_GLSLstd450_;
44  }
45
46  uint32_t GetExtInstImportId_OpenCL100DebugInfo() const {
47    return extinst_importid_OpenCL100DebugInfo_;
48  }
49
50  uint32_t GetExtInstImportId_Shader100DebugInfo() const {
51    return extinst_importid_Shader100DebugInfo_;
52  }
53
54  friend bool operator==(const FeatureManager& a, const FeatureManager& b);
55  friend bool operator!=(const FeatureManager& a, const FeatureManager& b) {
56    return !(a == b);
57  }
58
59 private:
60  explicit FeatureManager(const AssemblyGrammar& grammar) : grammar_(grammar) {}
61
62  // Analyzes |module| and records enabled extensions and capabilities.
63  void Analyze(Module* module);
64
65  // Add the extension |ext| to the feature manager.
66  void AddExtension(Instruction* ext);
67
68  // Analyzes |module| and records enabled extensions.
69  void AddExtensions(Module* module);
70
71  // Removes the given |extension| from the current FeatureManager.
72  void RemoveExtension(Extension extension);
73
74  // Adds the given |capability| and all implied capabilities into the current
75  // FeatureManager.
76  void AddCapability(spv::Capability capability);
77
78  // Analyzes |module| and records enabled capabilities.
79  void AddCapabilities(Module* module);
80
81  // Removes the given |capability| from the current FeatureManager.
82  void RemoveCapability(spv::Capability capability);
83
84  // Analyzes |module| and records imported external instruction sets.
85  void AddExtInstImportIds(Module* module);
86
87  // Auxiliary object for querying SPIR-V grammar facts.
88  const AssemblyGrammar& grammar_;
89
90  // The enabled extensions.
91  ExtensionSet extensions_;
92
93  // The enabled capabilities.
94  CapabilitySet capabilities_;
95
96  // Common external instruction import ids, cached for performance.
97  uint32_t extinst_importid_GLSLstd450_ = 0;
98
99  // Common OpenCL100DebugInfo external instruction import ids, cached
100  // for performance.
101  uint32_t extinst_importid_OpenCL100DebugInfo_ = 0;
102
103  // Common NonSemanticShader100DebugInfo external instruction import ids,
104  // cached for performance.
105  uint32_t extinst_importid_Shader100DebugInfo_ = 0;
106
107  friend class IRContext;
108};
109
110}  // namespace opt
111}  // namespace spvtools
112
113#endif  // SOURCE_OPT_FEATURE_MANAGER_H_
114