xref: /aosp_15_r20/external/angle/third_party/spirv-tools/src/source/val/instruction.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 // Copyright (c) 2015-2016 The Khronos Group 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_VAL_INSTRUCTION_H_
16 #define SOURCE_VAL_INSTRUCTION_H_
17 
18 #include <cassert>
19 #include <cstdint>
20 #include <functional>
21 #include <utility>
22 #include <vector>
23 
24 #include "source/ext_inst.h"
25 #include "source/opcode.h"
26 #include "source/table.h"
27 #include "spirv-tools/libspirv.h"
28 
29 namespace spvtools {
30 namespace val {
31 
32 class BasicBlock;
33 class Function;
34 
35 /// Wraps the spv_parsed_instruction struct along with use and definition of the
36 /// instruction's result id
37 class Instruction {
38  public:
39   explicit Instruction(const spv_parsed_instruction_t* inst);
40 
41   /// Registers the use of the Instruction in instruction \p inst at \p index
42   void RegisterUse(const Instruction* inst, uint32_t index);
43 
id()44   uint32_t id() const { return inst_.result_id; }
type_id()45   uint32_t type_id() const { return inst_.type_id; }
opcode()46   spv::Op opcode() const { return static_cast<spv::Op>(inst_.opcode); }
47 
48   /// Returns the Function where the instruction was defined. nullptr if it was
49   /// defined outside of a Function
function()50   const Function* function() const { return function_; }
set_function(Function * func)51   void set_function(Function* func) { function_ = func; }
52 
53   /// Returns the BasicBlock where the instruction was defined. nullptr if it
54   /// was defined outside of a BasicBlock
block()55   const BasicBlock* block() const { return block_; }
set_block(BasicBlock * b)56   void set_block(BasicBlock* b) { block_ = b; }
57 
58   /// Returns a vector of pairs of all references to this instruction's result
59   /// id. The first element is the instruction in which this result id was
60   /// referenced and the second is the index of the word in that instruction
61   /// where this result id appeared
uses()62   const std::vector<std::pair<const Instruction*, uint32_t>>& uses() const {
63     return uses_;
64   }
65 
66   /// The word used to define the Instruction
word(size_t index)67   uint32_t word(size_t index) const { return words_[index]; }
68 
69   /// The words used to define the Instruction
words()70   const std::vector<uint32_t>& words() const { return words_; }
71 
72   /// Returns the operand at |idx|.
operand(size_t idx)73   const spv_parsed_operand_t& operand(size_t idx) const {
74     return operands_[idx];
75   }
76 
77   /// The operands of the Instruction
operands()78   const std::vector<spv_parsed_operand_t>& operands() const {
79     return operands_;
80   }
81 
82   /// Provides direct access to the stored C instruction object.
c_inst()83   const spv_parsed_instruction_t& c_inst() const { return inst_; }
84 
85   /// Provides direct access to instructions spv_ext_inst_type_t object.
ext_inst_type()86   const spv_ext_inst_type_t& ext_inst_type() const {
87     return inst_.ext_inst_type;
88   }
89 
IsNonSemantic()90   bool IsNonSemantic() const {
91     return spvIsExtendedInstruction(opcode()) &&
92            spvExtInstIsNonSemantic(inst_.ext_inst_type);
93   }
94 
95   /// True if this is an OpExtInst for debug info extension.
IsDebugInfo()96   bool IsDebugInfo() const {
97     return spvIsExtendedInstruction(opcode()) &&
98            spvExtInstIsDebugInfo(inst_.ext_inst_type);
99   }
100 
101   // Casts the words belonging to the operand under |index| to |T| and returns.
102   template <typename T>
GetOperandAs(size_t index)103   T GetOperandAs(size_t index) const {
104     const spv_parsed_operand_t& o = operands_.at(index);
105     assert(o.num_words * 4 >= sizeof(T));
106     assert(o.offset + o.num_words <= inst_.num_words);
107     return *reinterpret_cast<const T*>(&words_[o.offset]);
108   }
109 
LineNum()110   size_t LineNum() const { return line_num_; }
SetLineNum(size_t pos)111   void SetLineNum(size_t pos) { line_num_ = pos; }
112 
113  private:
114   const std::vector<uint32_t> words_;
115   const std::vector<spv_parsed_operand_t> operands_;
116   spv_parsed_instruction_t inst_;
117   size_t line_num_ = 0;
118 
119   /// The function in which this instruction was declared
120   Function* function_ = nullptr;
121 
122   /// The basic block in which this instruction was declared
123   BasicBlock* block_ = nullptr;
124 
125   /// This is a vector of pairs of all references to this instruction's result
126   /// id. The first element is the instruction in which this result id was
127   /// referenced and the second is the index of the word in the referencing
128   /// instruction where this instruction appeared
129   std::vector<std::pair<const Instruction*, uint32_t>> uses_;
130 };
131 
132 bool operator<(const Instruction& lhs, const Instruction& rhs);
133 bool operator<(const Instruction& lhs, uint32_t rhs);
134 bool operator==(const Instruction& lhs, const Instruction& rhs);
135 bool operator==(const Instruction& lhs, uint32_t rhs);
136 
137 template <>
138 std::string Instruction::GetOperandAs<std::string>(size_t index) const;
139 
140 }  // namespace val
141 }  // namespace spvtools
142 
143 // custom specialization of std::hash for Instruction
144 namespace std {
145 template <>
146 struct hash<spvtools::val::Instruction> {
147   typedef spvtools::val::Instruction argument_type;
148   typedef std::size_t result_type;
149   result_type operator()(const argument_type& inst) const {
150     return hash<uint32_t>()(inst.id());
151   }
152 };
153 
154 }  // namespace std
155 
156 #endif  // SOURCE_VAL_INSTRUCTION_H_
157