instruction.h 5.2 KB

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