GenericMachineInstrs.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- llvm/CodeGen/GlobalISel/GenericMachineInstrs.h -----------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. /// \file
  14. /// Declares convenience wrapper classes for interpreting MachineInstr instances
  15. /// as specific generic operations.
  16. ///
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H
  19. #define LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H
  20. #include "llvm/IR/Instructions.h"
  21. #include "llvm/CodeGen/MachineInstr.h"
  22. #include "llvm/CodeGen/MachineMemOperand.h"
  23. #include "llvm/CodeGen/TargetOpcodes.h"
  24. #include "llvm/Support/Casting.h"
  25. namespace llvm {
  26. /// A base class for all GenericMachineInstrs.
  27. class GenericMachineInstr : public MachineInstr {
  28. public:
  29. GenericMachineInstr() = delete;
  30. /// Access the Idx'th operand as a register and return it.
  31. /// This assumes that the Idx'th operand is a Register type.
  32. Register getReg(unsigned Idx) const { return getOperand(Idx).getReg(); }
  33. static bool classof(const MachineInstr *MI) {
  34. return isPreISelGenericOpcode(MI->getOpcode());
  35. }
  36. };
  37. /// Represents any type of generic load or store.
  38. /// G_LOAD, G_STORE, G_ZEXTLOAD, G_SEXTLOAD.
  39. class GLoadStore : public GenericMachineInstr {
  40. public:
  41. /// Get the source register of the pointer value.
  42. Register getPointerReg() const { return getOperand(1).getReg(); }
  43. /// Get the MachineMemOperand on this instruction.
  44. MachineMemOperand &getMMO() const { return **memoperands_begin(); }
  45. /// Returns true if the attached MachineMemOperand has the atomic flag set.
  46. bool isAtomic() const { return getMMO().isAtomic(); }
  47. /// Returns true if the attached MachineMemOpeand as the volatile flag set.
  48. bool isVolatile() const { return getMMO().isVolatile(); }
  49. /// Returns true if the memory operation is neither atomic or volatile.
  50. bool isSimple() const { return !isAtomic() && !isVolatile(); }
  51. /// Returns true if this memory operation doesn't have any ordering
  52. /// constraints other than normal aliasing. Volatile and (ordered) atomic
  53. /// memory operations can't be reordered.
  54. bool isUnordered() const { return getMMO().isUnordered(); }
  55. /// Returns the size in bytes of the memory access.
  56. uint64_t getMemSize() const { return getMMO().getSize();
  57. } /// Returns the size in bits of the memory access.
  58. uint64_t getMemSizeInBits() const { return getMMO().getSizeInBits(); }
  59. static bool classof(const MachineInstr *MI) {
  60. switch (MI->getOpcode()) {
  61. case TargetOpcode::G_LOAD:
  62. case TargetOpcode::G_STORE:
  63. case TargetOpcode::G_ZEXTLOAD:
  64. case TargetOpcode::G_SEXTLOAD:
  65. return true;
  66. default:
  67. return false;
  68. }
  69. }
  70. };
  71. /// Represents any generic load, including sign/zero extending variants.
  72. class GAnyLoad : public GLoadStore {
  73. public:
  74. /// Get the definition register of the loaded value.
  75. Register getDstReg() const { return getOperand(0).getReg(); }
  76. static bool classof(const MachineInstr *MI) {
  77. switch (MI->getOpcode()) {
  78. case TargetOpcode::G_LOAD:
  79. case TargetOpcode::G_ZEXTLOAD:
  80. case TargetOpcode::G_SEXTLOAD:
  81. return true;
  82. default:
  83. return false;
  84. }
  85. }
  86. };
  87. /// Represents a G_LOAD.
  88. class GLoad : public GAnyLoad {
  89. public:
  90. static bool classof(const MachineInstr *MI) {
  91. return MI->getOpcode() == TargetOpcode::G_LOAD;
  92. }
  93. };
  94. /// Represents either a G_SEXTLOAD or G_ZEXTLOAD.
  95. class GExtLoad : public GAnyLoad {
  96. public:
  97. static bool classof(const MachineInstr *MI) {
  98. return MI->getOpcode() == TargetOpcode::G_SEXTLOAD ||
  99. MI->getOpcode() == TargetOpcode::G_ZEXTLOAD;
  100. }
  101. };
  102. /// Represents a G_SEXTLOAD.
  103. class GSExtLoad : public GExtLoad {
  104. public:
  105. static bool classof(const MachineInstr *MI) {
  106. return MI->getOpcode() == TargetOpcode::G_SEXTLOAD;
  107. }
  108. };
  109. /// Represents a G_ZEXTLOAD.
  110. class GZExtLoad : public GExtLoad {
  111. public:
  112. static bool classof(const MachineInstr *MI) {
  113. return MI->getOpcode() == TargetOpcode::G_ZEXTLOAD;
  114. }
  115. };
  116. /// Represents a G_STORE.
  117. class GStore : public GLoadStore {
  118. public:
  119. /// Get the stored value register.
  120. Register getValueReg() const { return getOperand(0).getReg(); }
  121. static bool classof(const MachineInstr *MI) {
  122. return MI->getOpcode() == TargetOpcode::G_STORE;
  123. }
  124. };
  125. /// Represents a G_UNMERGE_VALUES.
  126. class GUnmerge : public GenericMachineInstr {
  127. public:
  128. /// Returns the number of def registers.
  129. unsigned getNumDefs() const { return getNumOperands() - 1; }
  130. /// Get the unmerge source register.
  131. Register getSourceReg() const { return getOperand(getNumDefs()).getReg(); }
  132. static bool classof(const MachineInstr *MI) {
  133. return MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES;
  134. }
  135. };
  136. /// Represents G_BUILD_VECTOR, G_CONCAT_VECTORS or G_MERGE_VALUES.
  137. /// All these have the common property of generating a single value from
  138. /// multiple sources.
  139. class GMergeLikeInstr : public GenericMachineInstr {
  140. public:
  141. /// Returns the number of source registers.
  142. unsigned getNumSources() const { return getNumOperands() - 1; }
  143. /// Returns the I'th source register.
  144. Register getSourceReg(unsigned I) const { return getReg(I + 1); }
  145. static bool classof(const MachineInstr *MI) {
  146. switch (MI->getOpcode()) {
  147. case TargetOpcode::G_MERGE_VALUES:
  148. case TargetOpcode::G_CONCAT_VECTORS:
  149. case TargetOpcode::G_BUILD_VECTOR:
  150. return true;
  151. default:
  152. return false;
  153. }
  154. }
  155. };
  156. /// Represents a G_MERGE_VALUES.
  157. class GMerge : public GMergeLikeInstr {
  158. public:
  159. static bool classof(const MachineInstr *MI) {
  160. return MI->getOpcode() == TargetOpcode::G_MERGE_VALUES;
  161. }
  162. };
  163. /// Represents a G_CONCAT_VECTORS.
  164. class GConcatVectors : public GMergeLikeInstr {
  165. public:
  166. static bool classof(const MachineInstr *MI) {
  167. return MI->getOpcode() == TargetOpcode::G_CONCAT_VECTORS;
  168. }
  169. };
  170. /// Represents a G_BUILD_VECTOR.
  171. class GBuildVector : public GMergeLikeInstr {
  172. public:
  173. static bool classof(const MachineInstr *MI) {
  174. return MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR;
  175. }
  176. };
  177. /// Represents a G_PTR_ADD.
  178. class GPtrAdd : public GenericMachineInstr {
  179. public:
  180. Register getBaseReg() const { return getReg(1); }
  181. Register getOffsetReg() const { return getReg(2); }
  182. static bool classof(const MachineInstr *MI) {
  183. return MI->getOpcode() == TargetOpcode::G_PTR_ADD;
  184. }
  185. };
  186. /// Represents a G_IMPLICIT_DEF.
  187. class GImplicitDef : public GenericMachineInstr {
  188. public:
  189. static bool classof(const MachineInstr *MI) {
  190. return MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF;
  191. }
  192. };
  193. /// Represents a G_SELECT.
  194. class GSelect : public GenericMachineInstr {
  195. public:
  196. Register getCondReg() const { return getReg(1); }
  197. Register getTrueReg() const { return getReg(2); }
  198. Register getFalseReg() const { return getReg(3); }
  199. static bool classof(const MachineInstr *MI) {
  200. return MI->getOpcode() == TargetOpcode::G_SELECT;
  201. }
  202. };
  203. /// Represent a G_ICMP or G_FCMP.
  204. class GAnyCmp : public GenericMachineInstr {
  205. public:
  206. CmpInst::Predicate getCond() const {
  207. return static_cast<CmpInst::Predicate>(getOperand(1).getPredicate());
  208. }
  209. Register getLHSReg() const { return getReg(2); }
  210. Register getRHSReg() const { return getReg(3); }
  211. static bool classof(const MachineInstr *MI) {
  212. return MI->getOpcode() == TargetOpcode::G_ICMP ||
  213. MI->getOpcode() == TargetOpcode::G_FCMP;
  214. }
  215. };
  216. /// Represent a G_ICMP.
  217. class GICmp : public GAnyCmp {
  218. public:
  219. static bool classof(const MachineInstr *MI) {
  220. return MI->getOpcode() == TargetOpcode::G_ICMP;
  221. }
  222. };
  223. /// Represent a G_FCMP.
  224. class GFCmp : public GAnyCmp {
  225. public:
  226. static bool classof(const MachineInstr *MI) {
  227. return MI->getOpcode() == TargetOpcode::G_FCMP;
  228. }
  229. };
  230. } // namespace llvm
  231. #endif // LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H
  232. #ifdef __GNUC__
  233. #pragma GCC diagnostic pop
  234. #endif