Roll external/abseil_cpp/ 8f739d18b..917bfee46 (2 commits) (#5887)
[KhronosGroup/SPIRV-Tools.git] / source / val / instruction.h
blob59e8af13b1db223cb0f21cb6d2eb6e5096b79d83
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.
15 #ifndef SOURCE_VAL_INSTRUCTION_H_
16 #define SOURCE_VAL_INSTRUCTION_H_
18 #include <cassert>
19 #include <cstdint>
20 #include <functional>
21 #include <utility>
22 #include <vector>
24 #include "source/ext_inst.h"
25 #include "source/opcode.h"
26 #include "source/table.h"
27 #include "spirv-tools/libspirv.h"
29 namespace spvtools {
30 namespace val {
32 class BasicBlock;
33 class Function;
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);
41 /// Registers the use of the Instruction in instruction \p inst at \p index
42 void RegisterUse(const Instruction* inst, uint32_t index);
44 uint32_t id() const { return inst_.result_id; }
45 uint32_t type_id() const { return inst_.type_id; }
46 spv::Op opcode() const { return static_cast<spv::Op>(inst_.opcode); }
48 /// Returns the Function where the instruction was defined. nullptr if it was
49 /// defined outside of a Function
50 const Function* function() const { return function_; }
51 void set_function(Function* func) { function_ = func; }
53 /// Returns the BasicBlock where the instruction was defined. nullptr if it
54 /// was defined outside of a BasicBlock
55 const BasicBlock* block() const { return block_; }
56 void set_block(BasicBlock* b) { block_ = b; }
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
62 const std::vector<std::pair<const Instruction*, uint32_t>>& uses() const {
63 return uses_;
66 /// The word used to define the Instruction
67 uint32_t word(size_t index) const { return words_[index]; }
69 /// The words used to define the Instruction
70 const std::vector<uint32_t>& words() const { return words_; }
72 /// Returns the operand at |idx|.
73 const spv_parsed_operand_t& operand(size_t idx) const {
74 return operands_[idx];
77 /// The operands of the Instruction
78 const std::vector<spv_parsed_operand_t>& operands() const {
79 return operands_;
82 /// Provides direct access to the stored C instruction object.
83 const spv_parsed_instruction_t& c_inst() const { return inst_; }
85 /// Provides direct access to instructions spv_ext_inst_type_t object.
86 const spv_ext_inst_type_t& ext_inst_type() const {
87 return inst_.ext_inst_type;
90 bool IsNonSemantic() const {
91 return spvIsExtendedInstruction(opcode()) &&
92 spvExtInstIsNonSemantic(inst_.ext_inst_type);
95 /// True if this is an OpExtInst for debug info extension.
96 bool IsDebugInfo() const {
97 return spvIsExtendedInstruction(opcode()) &&
98 spvExtInstIsDebugInfo(inst_.ext_inst_type);
101 // Casts the words belonging to the operand under |index| to |T| and returns.
102 template <typename T>
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]);
110 size_t LineNum() const { return line_num_; }
111 void SetLineNum(size_t pos) { line_num_ = pos; }
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;
119 /// The function in which this instruction was declared
120 Function* function_ = nullptr;
122 /// The basic block in which this instruction was declared
123 BasicBlock* block_ = nullptr;
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_;
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);
137 template <>
138 std::string Instruction::GetOperandAs<std::string>(size_t index) const;
140 } // namespace val
141 } // namespace spvtools
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());
154 } // namespace std
156 #endif // SOURCE_VAL_INSTRUCTION_H_