instruction.h 5.2 KB

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