RISCVInstrInfo.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. //===-- RISCVInstrInfo.h - RISCV Instruction Information --------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file contains the RISCV implementation of the TargetInstrInfo class.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H
  13. #define LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H
  14. #include "RISCVRegisterInfo.h"
  15. #include "llvm/CodeGen/TargetInstrInfo.h"
  16. #include "llvm/IR/DiagnosticInfo.h"
  17. #define GET_INSTRINFO_HEADER
  18. #define GET_INSTRINFO_OPERAND_ENUM
  19. #include "RISCVGenInstrInfo.inc"
  20. namespace llvm {
  21. class RISCVSubtarget;
  22. namespace RISCVCC {
  23. enum CondCode {
  24. COND_EQ,
  25. COND_NE,
  26. COND_LT,
  27. COND_GE,
  28. COND_LTU,
  29. COND_GEU,
  30. COND_INVALID
  31. };
  32. CondCode getOppositeBranchCondition(CondCode);
  33. } // end of namespace RISCVCC
  34. class RISCVInstrInfo : public RISCVGenInstrInfo {
  35. public:
  36. explicit RISCVInstrInfo(RISCVSubtarget &STI);
  37. MCInst getNop() const override;
  38. const MCInstrDesc &getBrCond(RISCVCC::CondCode CC) const;
  39. unsigned isLoadFromStackSlot(const MachineInstr &MI,
  40. int &FrameIndex) const override;
  41. unsigned isStoreToStackSlot(const MachineInstr &MI,
  42. int &FrameIndex) const override;
  43. void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
  44. const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg,
  45. bool KillSrc) const override;
  46. void storeRegToStackSlot(MachineBasicBlock &MBB,
  47. MachineBasicBlock::iterator MBBI, Register SrcReg,
  48. bool IsKill, int FrameIndex,
  49. const TargetRegisterClass *RC,
  50. const TargetRegisterInfo *TRI,
  51. Register VReg) const override;
  52. void loadRegFromStackSlot(MachineBasicBlock &MBB,
  53. MachineBasicBlock::iterator MBBI, Register DstReg,
  54. int FrameIndex, const TargetRegisterClass *RC,
  55. const TargetRegisterInfo *TRI,
  56. Register VReg) const override;
  57. using TargetInstrInfo::foldMemoryOperandImpl;
  58. MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI,
  59. ArrayRef<unsigned> Ops,
  60. MachineBasicBlock::iterator InsertPt,
  61. int FrameIndex,
  62. LiveIntervals *LIS = nullptr,
  63. VirtRegMap *VRM = nullptr) const override;
  64. // Materializes the given integer Val into DstReg.
  65. void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
  66. const DebugLoc &DL, Register DstReg, uint64_t Val,
  67. MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const;
  68. unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
  69. bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
  70. MachineBasicBlock *&FBB,
  71. SmallVectorImpl<MachineOperand> &Cond,
  72. bool AllowModify) const override;
  73. unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
  74. MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
  75. const DebugLoc &dl,
  76. int *BytesAdded = nullptr) const override;
  77. void insertIndirectBranch(MachineBasicBlock &MBB,
  78. MachineBasicBlock &NewDestBB,
  79. MachineBasicBlock &RestoreBB, const DebugLoc &DL,
  80. int64_t BrOffset, RegScavenger *RS) const override;
  81. unsigned removeBranch(MachineBasicBlock &MBB,
  82. int *BytesRemoved = nullptr) const override;
  83. bool
  84. reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
  85. MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
  86. bool isBranchOffsetInRange(unsigned BranchOpc,
  87. int64_t BrOffset) const override;
  88. bool analyzeSelect(const MachineInstr &MI,
  89. SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp,
  90. unsigned &FalseOp, bool &Optimizable) const override;
  91. MachineInstr *optimizeSelect(MachineInstr &MI,
  92. SmallPtrSetImpl<MachineInstr *> &SeenMIs,
  93. bool) const override;
  94. bool isAsCheapAsAMove(const MachineInstr &MI) const override;
  95. std::optional<DestSourcePair>
  96. isCopyInstrImpl(const MachineInstr &MI) const override;
  97. bool verifyInstruction(const MachineInstr &MI,
  98. StringRef &ErrInfo) const override;
  99. bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt,
  100. const MachineOperand *&BaseOp,
  101. int64_t &Offset, unsigned &Width,
  102. const TargetRegisterInfo *TRI) const;
  103. bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
  104. const MachineInstr &MIb) const override;
  105. std::pair<unsigned, unsigned>
  106. decomposeMachineOperandsTargetFlags(unsigned TF) const override;
  107. ArrayRef<std::pair<unsigned, const char *>>
  108. getSerializableDirectMachineOperandTargetFlags() const override;
  109. // Return true if the function can safely be outlined from.
  110. bool isFunctionSafeToOutlineFrom(MachineFunction &MF,
  111. bool OutlineFromLinkOnceODRs) const override;
  112. // Return true if MBB is safe to outline from, and return any target-specific
  113. // information in Flags.
  114. bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,
  115. unsigned &Flags) const override;
  116. bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override;
  117. // Calculate target-specific information for a set of outlining candidates.
  118. outliner::OutlinedFunction getOutliningCandidateInfo(
  119. std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override;
  120. // Return if/how a given MachineInstr should be outlined.
  121. outliner::InstrType getOutliningType(MachineBasicBlock::iterator &MBBI,
  122. unsigned Flags) const override;
  123. // Insert a custom frame for outlined functions.
  124. void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF,
  125. const outliner::OutlinedFunction &OF) const override;
  126. // Insert a call to an outlined function into a given basic block.
  127. MachineBasicBlock::iterator
  128. insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
  129. MachineBasicBlock::iterator &It, MachineFunction &MF,
  130. outliner::Candidate &C) const override;
  131. bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1,
  132. unsigned &SrcOpIdx2) const override;
  133. MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
  134. unsigned OpIdx1,
  135. unsigned OpIdx2) const override;
  136. MachineInstr *convertToThreeAddress(MachineInstr &MI, LiveVariables *LV,
  137. LiveIntervals *LIS) const override;
  138. // MIR printer helper function to annotate Operands with a comment.
  139. std::string
  140. createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op,
  141. unsigned OpIdx,
  142. const TargetRegisterInfo *TRI) const override;
  143. void getVLENFactoredAmount(
  144. MachineFunction &MF, MachineBasicBlock &MBB,
  145. MachineBasicBlock::iterator II, const DebugLoc &DL, Register DestReg,
  146. int64_t Amount, MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const;
  147. bool useMachineCombiner() const override { return true; }
  148. void setSpecialOperandAttr(MachineInstr &OldMI1, MachineInstr &OldMI2,
  149. MachineInstr &NewMI1,
  150. MachineInstr &NewMI2) const override;
  151. bool
  152. getMachineCombinerPatterns(MachineInstr &Root,
  153. SmallVectorImpl<MachineCombinerPattern> &Patterns,
  154. bool DoRegPressureReduce) const override;
  155. void
  156. finalizeInsInstrs(MachineInstr &Root, MachineCombinerPattern &P,
  157. SmallVectorImpl<MachineInstr *> &InsInstrs) const override;
  158. void genAlternativeCodeSequence(
  159. MachineInstr &Root, MachineCombinerPattern Pattern,
  160. SmallVectorImpl<MachineInstr *> &InsInstrs,
  161. SmallVectorImpl<MachineInstr *> &DelInstrs,
  162. DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const override;
  163. bool hasReassociableSibling(const MachineInstr &Inst,
  164. bool &Commuted) const override;
  165. bool isAssociativeAndCommutative(const MachineInstr &Inst,
  166. bool Invert) const override;
  167. std::optional<unsigned> getInverseOpcode(unsigned Opcode) const override;
  168. // Returns true if all uses of OrigMI only depend on the lower \p NBits bits
  169. // of its output.
  170. bool hasAllNBitUsers(const MachineInstr &MI, const MachineRegisterInfo &MRI,
  171. unsigned NBits) const;
  172. // Returns true if all uses of OrigMI only depend on the lower word of its
  173. // output, so we can transform OrigMI to the corresponding W-version.
  174. bool hasAllWUsers(const MachineInstr &MI,
  175. const MachineRegisterInfo &MRI) const {
  176. return hasAllNBitUsers(MI, MRI, 32);
  177. }
  178. protected:
  179. const RISCVSubtarget &STI;
  180. };
  181. namespace RISCV {
  182. // Returns true if this is the sext.w pattern, addiw rd, rs1, 0.
  183. bool isSEXT_W(const MachineInstr &MI);
  184. bool isZEXT_W(const MachineInstr &MI);
  185. bool isZEXT_B(const MachineInstr &MI);
  186. // Returns true if the given MI is an RVV instruction opcode for which we may
  187. // expect to see a FrameIndex operand.
  188. bool isRVVSpill(const MachineInstr &MI);
  189. std::optional<std::pair<unsigned, unsigned>>
  190. isRVVSpillForZvlsseg(unsigned Opcode);
  191. bool isFaultFirstLoad(const MachineInstr &MI);
  192. // Implemented in RISCVGenInstrInfo.inc
  193. int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex);
  194. // Return true if both input instructions have equal rounding mode. If at least
  195. // one of the instructions does not have rounding mode, false will be returned.
  196. bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2);
  197. // Special immediate for AVL operand of V pseudo instructions to indicate VLMax.
  198. static constexpr int64_t VLMaxSentinel = -1LL;
  199. } // namespace RISCV
  200. namespace RISCVVPseudosTable {
  201. struct PseudoInfo {
  202. uint16_t Pseudo;
  203. uint16_t BaseInstr;
  204. };
  205. #define GET_RISCVVPseudosTable_DECL
  206. #include "RISCVGenSearchableTables.inc"
  207. } // end namespace RISCVVPseudosTable
  208. } // end namespace llvm
  209. #endif