Coverage Report

Created: 2025-12-31 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/spirv-tools/source/val/instruction.h
Line
Count
Source
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 "source/table2.h"
28
#include "spirv-tools/libspirv.h"
29
30
namespace spvtools {
31
namespace val {
32
33
class BasicBlock;
34
class Function;
35
36
/// Wraps the spv_parsed_instruction struct along with use and definition of the
37
/// instruction's result id
38
class Instruction {
39
 public:
40
  explicit Instruction(const spv_parsed_instruction_t* inst);
41
42
  /// Registers the use of the Instruction in instruction \p inst at \p index
43
  void RegisterUse(const Instruction* inst, uint32_t index);
44
45
46.6M
  uint32_t id() const { return inst_.result_id; }
46
226M
  uint32_t type_id() const { return inst_.type_id; }
47
1.11G
  spv::Op opcode() const { return static_cast<spv::Op>(inst_.opcode); }
48
49
  /// Returns the Function where the instruction was defined. nullptr if it was
50
  /// defined outside of a Function
51
19.3M
  const Function* function() const { return function_; }
52
2.63M
  void set_function(Function* func) { function_ = func; }
53
54
  /// Returns the BasicBlock where the instruction was defined. nullptr if it
55
  /// was defined outside of a BasicBlock
56
4.33M
  const BasicBlock* block() const { return block_; }
57
2.63M
  void set_block(BasicBlock* b) { block_ = b; }
58
59
  /// Returns a vector of pairs of all references to this instruction's result
60
  /// id. The first element is the instruction in which this result id was
61
  /// referenced and the second is the index of the word in that instruction
62
  /// where this result id appeared
63
2.54M
  const std::vector<std::pair<const Instruction*, uint32_t>>& uses() const {
64
2.54M
    return uses_;
65
2.54M
  }
66
67
  /// The word used to define the Instruction
68
98.1M
  uint32_t word(size_t index) const { return words_[index]; }
69
70
  /// The words used to define the Instruction
71
38.6M
  const std::vector<uint32_t>& words() const { return words_; }
72
73
  /// Returns the operand at |idx|.
74
88.3M
  const spv_parsed_operand_t& operand(size_t idx) const {
75
88.3M
    return operands_[idx];
76
88.3M
  }
77
78
  /// The operands of the Instruction
79
214M
  const std::vector<spv_parsed_operand_t>& operands() const {
80
214M
    return operands_;
81
214M
  }
82
83
  /// Provides direct access to the stored C instruction object.
84
44.7k
  const spv_parsed_instruction_t& c_inst() const { return inst_; }
85
86
  /// Provides direct access to instructions spv_ext_inst_type_t object.
87
243k
  spv_ext_inst_type_t ext_inst_type() const { return inst_.ext_inst_type; }
88
89
23.2M
  bool IsNonSemantic() const {
90
23.2M
    return spvIsExtendedInstruction(opcode()) &&
91
159k
           spvExtInstIsNonSemantic(inst_.ext_inst_type);
92
23.2M
  }
93
94
  /// True if this is an OpExtInst for debug info extension.
95
10.3M
  bool IsDebugInfo() const {
96
10.3M
    return spvIsExtendedInstruction(opcode()) &&
97
52.9k
           spvExtInstIsDebugInfo(inst_.ext_inst_type);
98
10.3M
  }
99
100
  // Casts the words belonging to the operand under |index| to |T| and returns.
101
  template <typename T>
102
43.4M
  T GetOperandAs(size_t index) const {
103
43.4M
    const spv_parsed_operand_t& o = operands_.at(index);
104
43.4M
    assert(o.num_words * 4 >= sizeof(T));
105
43.4M
    assert(o.offset + o.num_words <= inst_.num_words);
106
43.4M
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
43.4M
  }
unsigned int spvtools::val::Instruction::GetOperandAs<unsigned int>(unsigned long) const
Line
Count
Source
102
35.9M
  T GetOperandAs(size_t index) const {
103
35.9M
    const spv_parsed_operand_t& o = operands_.at(index);
104
35.9M
    assert(o.num_words * 4 >= sizeof(T));
105
35.9M
    assert(o.offset + o.num_words <= inst_.num_words);
106
35.9M
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
35.9M
  }
spv::ExecutionModel spvtools::val::Instruction::GetOperandAs<spv::ExecutionModel>(unsigned long) const
Line
Count
Source
102
72.8k
  T GetOperandAs(size_t index) const {
103
72.8k
    const spv_parsed_operand_t& o = operands_.at(index);
104
72.8k
    assert(o.num_words * 4 >= sizeof(T));
105
72.8k
    assert(o.offset + o.num_words <= inst_.num_words);
106
72.8k
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
72.8k
  }
spv::StorageClass spvtools::val::Instruction::GetOperandAs<spv::StorageClass>(unsigned long) const
Line
Count
Source
102
5.21M
  T GetOperandAs(size_t index) const {
103
5.21M
    const spv_parsed_operand_t& o = operands_.at(index);
104
5.21M
    assert(o.num_words * 4 >= sizeof(T));
105
5.21M
    assert(o.offset + o.num_words <= inst_.num_words);
106
5.21M
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
5.21M
  }
spv::Decoration spvtools::val::Instruction::GetOperandAs<spv::Decoration>(unsigned long) const
Line
Count
Source
102
1.73M
  T GetOperandAs(size_t index) const {
103
1.73M
    const spv_parsed_operand_t& o = operands_.at(index);
104
1.73M
    assert(o.num_words * 4 >= sizeof(T));
105
1.73M
    assert(o.offset + o.num_words <= inst_.num_words);
106
1.73M
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
1.73M
  }
spv::FPFastMathModeMask spvtools::val::Instruction::GetOperandAs<spv::FPFastMathModeMask>(unsigned long) const
Line
Count
Source
102
5.13k
  T GetOperandAs(size_t index) const {
103
5.13k
    const spv_parsed_operand_t& o = operands_.at(index);
104
5.13k
    assert(o.num_words * 4 >= sizeof(T));
105
5.13k
    assert(o.offset + o.num_words <= inst_.num_words);
106
5.13k
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
5.13k
  }
spv::BuiltIn spvtools::val::Instruction::GetOperandAs<spv::BuiltIn>(unsigned long) const
Line
Count
Source
102
6.98k
  T GetOperandAs(size_t index) const {
103
6.98k
    const spv_parsed_operand_t& o = operands_.at(index);
104
6.98k
    assert(o.num_words * 4 >= sizeof(T));
105
6.98k
    assert(o.offset + o.num_words <= inst_.num_words);
106
6.98k
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
6.98k
  }
unsigned int const spvtools::val::Instruction::GetOperandAs<unsigned int const>(unsigned long) const
Line
Count
Source
102
88.2k
  T GetOperandAs(size_t index) const {
103
88.2k
    const spv_parsed_operand_t& o = operands_.at(index);
104
88.2k
    assert(o.num_words * 4 >= sizeof(T));
105
88.2k
    assert(o.offset + o.num_words <= inst_.num_words);
106
88.2k
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
88.2k
  }
spv::LoopControlShift spvtools::val::Instruction::GetOperandAs<spv::LoopControlShift>(unsigned long) const
Line
Count
Source
102
37.4k
  T GetOperandAs(size_t index) const {
103
37.4k
    const spv_parsed_operand_t& o = operands_.at(index);
104
37.4k
    assert(o.num_words * 4 >= sizeof(T));
105
37.4k
    assert(o.offset + o.num_words <= inst_.num_words);
106
37.4k
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
37.4k
  }
spv::Op spvtools::val::Instruction::GetOperandAs<spv::Op>(unsigned long) const
Line
Count
Source
102
124
  T GetOperandAs(size_t index) const {
103
124
    const spv_parsed_operand_t& o = operands_.at(index);
104
124
    assert(o.num_words * 4 >= sizeof(T));
105
124
    assert(o.offset + o.num_words <= inst_.num_words);
106
124
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
124
  }
Unexecuted instantiation: NonSemanticClspvReflectionInstructions spvtools::val::Instruction::GetOperandAs<NonSemanticClspvReflectionInstructions>(unsigned long) const
int spvtools::val::Instruction::GetOperandAs<int>(unsigned long) const
Line
Count
Source
102
11.3k
  T GetOperandAs(size_t index) const {
103
11.3k
    const spv_parsed_operand_t& o = operands_.at(index);
104
11.3k
    assert(o.num_words * 4 >= sizeof(T));
105
11.3k
    assert(o.offset + o.num_words <= inst_.num_words);
106
11.3k
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
11.3k
  }
Unexecuted instantiation: spv::FPEncoding spvtools::val::Instruction::GetOperandAs<spv::FPEncoding>(unsigned long) const
spv::Capability spvtools::val::Instruction::GetOperandAs<spv::Capability>(unsigned long) const
Line
Count
Source
102
97.0k
  T GetOperandAs(size_t index) const {
103
97.0k
    const spv_parsed_operand_t& o = operands_.at(index);
104
97.0k
    assert(o.num_words * 4 >= sizeof(T));
105
97.0k
    assert(o.offset + o.num_words <= inst_.num_words);
106
97.0k
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
97.0k
  }
spv::AddressingModel spvtools::val::Instruction::GetOperandAs<spv::AddressingModel>(unsigned long) const
Line
Count
Source
102
41.0k
  T GetOperandAs(size_t index) const {
103
41.0k
    const spv_parsed_operand_t& o = operands_.at(index);
104
41.0k
    assert(o.num_words * 4 >= sizeof(T));
105
41.0k
    assert(o.offset + o.num_words <= inst_.num_words);
106
41.0k
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
41.0k
  }
spv::MemoryModel spvtools::val::Instruction::GetOperandAs<spv::MemoryModel>(unsigned long) const
Line
Count
Source
102
41.0k
  T GetOperandAs(size_t index) const {
103
41.0k
    const spv_parsed_operand_t& o = operands_.at(index);
104
41.0k
    assert(o.num_words * 4 >= sizeof(T));
105
41.0k
    assert(o.offset + o.num_words <= inst_.num_words);
106
41.0k
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
41.0k
  }
spv::ExecutionMode spvtools::val::Instruction::GetOperandAs<spv::ExecutionMode>(unsigned long) const
Line
Count
Source
102
153k
  T GetOperandAs(size_t index) const {
103
153k
    const spv_parsed_operand_t& o = operands_.at(index);
104
153k
    assert(o.num_words * 4 >= sizeof(T));
105
153k
    assert(o.offset + o.num_words <= inst_.num_words);
106
153k
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
153k
  }
spv::FunctionControlMask spvtools::val::Instruction::GetOperandAs<spv::FunctionControlMask>(unsigned long) const
Line
Count
Source
102
47.3k
  T GetOperandAs(size_t index) const {
103
47.3k
    const spv_parsed_operand_t& o = operands_.at(index);
104
47.3k
    assert(o.num_words * 4 >= sizeof(T));
105
47.3k
    assert(o.offset + o.num_words <= inst_.num_words);
106
47.3k
    return *reinterpret_cast<const T*>(&words_[o.offset]);
107
47.3k
  }
Unexecuted instantiation: spv::TensorAddressingOperandsMask spvtools::val::Instruction::GetOperandAs<spv::TensorAddressingOperandsMask>(unsigned long) const
Unexecuted instantiation: spv::GroupOperation spvtools::val::Instruction::GetOperandAs<spv::GroupOperation>(unsigned long) const
108
109
41.2k
  size_t LineNum() const { return line_num_; }
110
13.8M
  void SetLineNum(size_t pos) { line_num_ = pos; }
111
112
 private:
113
  const std::vector<uint32_t> words_;
114
  const std::vector<spv_parsed_operand_t> operands_;
115
  const spv_parsed_instruction_t inst_;
116
  size_t line_num_ = 0;
117
118
  /// The function in which this instruction was declared
119
  Function* function_ = nullptr;
120
121
  /// The basic block in which this instruction was declared
122
  BasicBlock* block_ = nullptr;
123
124
  /// This is a vector of pairs of all references to this instruction's result
125
  /// id. The first element is the instruction in which this result id was
126
  /// referenced and the second is the index of the word in the referencing
127
  /// instruction where this instruction appeared
128
  std::vector<std::pair<const Instruction*, uint32_t>> uses_;
129
};
130
131
bool operator<(const Instruction& lhs, const Instruction& rhs);
132
bool operator<(const Instruction& lhs, uint32_t rhs);
133
bool operator==(const Instruction& lhs, const Instruction& rhs);
134
bool operator==(const Instruction& lhs, uint32_t rhs);
135
136
template <>
137
std::string Instruction::GetOperandAs<std::string>(size_t index) const;
138
139
}  // namespace val
140
}  // namespace spvtools
141
142
// custom specialization of std::hash for Instruction
143
namespace std {
144
template <>
145
struct hash<spvtools::val::Instruction> {
146
  typedef spvtools::val::Instruction argument_type;
147
  typedef std::size_t result_type;
148
0
  result_type operator()(const argument_type& inst) const {
149
0
    return hash<uint32_t>()(inst.id());
150
0
  }
151
};
152
153
}  // namespace std
154
155
#endif  // SOURCE_VAL_INSTRUCTION_H_