1 // Copyright (c) 2015-2016 The Khronos Group Inc.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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_
24 #include "source/ext_inst.h"
25 #include "source/opcode.h"
26 #include "source/table.h"
27 #include "spirv-tools/libspirv.h"
35 /// Wraps the spv_parsed_instruction struct along with use and definition of the
36 /// instruction's result id
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 {
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 {
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
; }
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
);
138 std::string
Instruction::GetOperandAs
<std::string
>(size_t index
) const;
141 } // namespace spvtools
143 // custom specialization of std::hash for Instruction
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());
156 #endif // SOURCE_VAL_INSTRUCTION_H_