• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "module.h"
16 
17 #include <algorithm>
18 #include <cstring>
19 
20 #include "operand.h"
21 #include "reflect.h"
22 
23 namespace spvtools {
24 namespace ir {
25 
GetTypes()26 std::vector<Instruction*> Module::GetTypes() {
27   std::vector<Instruction*> insts;
28   for (uint32_t i = 0; i < types_values_.size(); ++i) {
29     if (IsTypeInst(types_values_[i]->opcode()))
30       insts.push_back(types_values_[i].get());
31   }
32   return insts;
33 };
34 
GetTypes() const35 std::vector<const Instruction*> Module::GetTypes() const {
36   std::vector<const Instruction*> insts;
37   for (uint32_t i = 0; i < types_values_.size(); ++i) {
38     if (IsTypeInst(types_values_[i]->opcode()))
39       insts.push_back(types_values_[i].get());
40   }
41   return insts;
42 };
43 
GetConstants()44 std::vector<Instruction*> Module::GetConstants() {
45   std::vector<Instruction*> insts;
46   for (uint32_t i = 0; i < types_values_.size(); ++i) {
47     if (IsConstantInst(types_values_[i]->opcode()))
48       insts.push_back(types_values_[i].get());
49   }
50   return insts;
51 };
52 
GetConstants() const53 std::vector<const Instruction*> Module::GetConstants() const {
54   std::vector<const Instruction*> insts;
55   for (uint32_t i = 0; i < types_values_.size(); ++i) {
56     if (IsConstantInst(types_values_[i]->opcode()))
57       insts.push_back(types_values_[i].get());
58   }
59   return insts;
60 };
61 
GetGlobalValue(SpvOp opcode) const62 uint32_t Module::GetGlobalValue(SpvOp opcode) const {
63   for (uint32_t i = 0; i < types_values_.size(); ++i) {
64     if (types_values_[i]->opcode() == opcode)
65       return types_values_[i]->result_id();
66   }
67   return 0;
68 }
69 
AddGlobalValue(SpvOp opcode,uint32_t result_id,uint32_t type_id)70 void Module::AddGlobalValue(SpvOp opcode, uint32_t result_id,
71                             uint32_t type_id) {
72   std::unique_ptr<ir::Instruction> newGlobal(
73       new ir::Instruction(opcode, type_id, result_id, {}));
74   AddGlobalValue(std::move(newGlobal));
75 }
76 
ForEachInst(const std::function<void (Instruction *)> & f,bool run_on_debug_line_insts)77 void Module::ForEachInst(const std::function<void(Instruction*)>& f,
78                          bool run_on_debug_line_insts) {
79 #define DELEGATE(i) i->ForEachInst(f, run_on_debug_line_insts)
80   for (auto& i : capabilities_) DELEGATE(i);
81   for (auto& i : extensions_) DELEGATE(i);
82   for (auto& i : ext_inst_imports_) DELEGATE(i);
83   if (memory_model_) DELEGATE(memory_model_);
84   for (auto& i : entry_points_) DELEGATE(i);
85   for (auto& i : execution_modes_) DELEGATE(i);
86   for (auto& i : debugs_) DELEGATE(i);
87   for (auto& i : annotations_) DELEGATE(i);
88   for (auto& i : types_values_) DELEGATE(i);
89   for (auto& i : functions_) DELEGATE(i);
90 #undef DELEGATE
91 }
92 
ForEachInst(const std::function<void (const Instruction *)> & f,bool run_on_debug_line_insts) const93 void Module::ForEachInst(const std::function<void(const Instruction*)>& f,
94                          bool run_on_debug_line_insts) const {
95 #define DELEGATE(i)                                      \
96   static_cast<const Instruction*>(i.get())->ForEachInst( \
97       f, run_on_debug_line_insts)
98   for (auto& i : capabilities_) DELEGATE(i);
99   for (auto& i : extensions_) DELEGATE(i);
100   for (auto& i : ext_inst_imports_) DELEGATE(i);
101   if (memory_model_) DELEGATE(memory_model_);
102   for (auto& i : entry_points_) DELEGATE(i);
103   for (auto& i : execution_modes_) DELEGATE(i);
104   for (auto& i : debugs_) DELEGATE(i);
105   for (auto& i : annotations_) DELEGATE(i);
106   for (auto& i : types_values_) DELEGATE(i);
107   for (auto& i : functions_) {
108     static_cast<const Function*>(i.get())->ForEachInst(f,
109                                                        run_on_debug_line_insts);
110   }
111 #undef DELEGATE
112 }
113 
ToBinary(std::vector<uint32_t> * binary,bool skip_nop) const114 void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
115   binary->push_back(header_.magic_number);
116   binary->push_back(header_.version);
117   // TODO(antiagainst): should we change the generator number?
118   binary->push_back(header_.generator);
119   binary->push_back(header_.bound);
120   binary->push_back(header_.reserved);
121 
122   auto write_inst = [binary, skip_nop](const Instruction* i) {
123     if (!(skip_nop && i->IsNop())) i->ToBinaryWithoutAttachedDebugInsts(binary);
124   };
125   ForEachInst(write_inst, true);
126 }
127 
ComputeIdBound() const128 uint32_t Module::ComputeIdBound() const {
129   uint32_t highest = 0;
130 
131   ForEachInst(
132       [&highest](const Instruction* inst) {
133         for (const auto& operand : *inst) {
134           if (spvIsIdType(operand.type)) {
135             highest = std::max(highest, operand.words[0]);
136           }
137         }
138       },
139       true /* scan debug line insts as well */);
140 
141   return highest + 1;
142 }
143 
HasCapability(uint32_t cap)144 bool Module::HasCapability(uint32_t cap) {
145   for (auto& ci : capabilities_) {
146     uint32_t tcap = ci->GetSingleWordOperand(0);
147     if (tcap == cap) {
148       return true;
149     }
150   }
151   return false;
152 }
153 
GetExtInstImportId(const char * extstr)154 uint32_t Module::GetExtInstImportId(const char* extstr) {
155   for (auto& ei : ext_inst_imports_)
156     if (!strcmp(extstr, reinterpret_cast<const char*>(
157         &ei->GetInOperand(0).words[0])))
158       return ei->result_id();
159   return 0;
160 }
161 
162 }  // namespace ir
163 }  // namespace spvtools
164