1 //===-- RISCVInstrInfo.h - RISC-V 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 RISC-V implementation of the TargetInstrInfo class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H 14 #define LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H 15 16 #include "RISCVRegisterInfo.h" 17 #include "llvm/CodeGen/TargetInstrInfo.h" 18 #include "llvm/IR/DiagnosticInfo.h" 19 20 #define GET_INSTRINFO_HEADER 21 #define GET_INSTRINFO_OPERAND_ENUM 22 #include "RISCVGenInstrInfo.inc" 23 24 namespace llvm { 25 26 class RISCVSubtarget; 27 28 static const MachineMemOperand::Flags MONontemporalBit0 = 29 MachineMemOperand::MOTargetFlag1; 30 static const MachineMemOperand::Flags MONontemporalBit1 = 31 MachineMemOperand::MOTargetFlag2; 32 33 namespace RISCVCC { 34 35 enum CondCode { 36 COND_EQ, 37 COND_NE, 38 COND_LT, 39 COND_GE, 40 COND_LTU, 41 COND_GEU, 42 COND_INVALID 43 }; 44 45 CondCode getOppositeBranchCondition(CondCode); 46 47 } // end of namespace RISCVCC 48 49 class RISCVInstrInfo : public RISCVGenInstrInfo { 50 51 public: 52 explicit RISCVInstrInfo(RISCVSubtarget &STI); 53 54 MCInst getNop() const override; 55 const MCInstrDesc &getBrCond(RISCVCC::CondCode CC) const; 56 57 unsigned isLoadFromStackSlot(const MachineInstr &MI, 58 int &FrameIndex) const override; 59 unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex, 60 unsigned &MemBytes) const override; 61 unsigned isStoreToStackSlot(const MachineInstr &MI, 62 int &FrameIndex) const override; 63 unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex, 64 unsigned &MemBytes) const override; 65 66 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 67 const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, 68 bool KillSrc) const override; 69 70 void storeRegToStackSlot(MachineBasicBlock &MBB, 71 MachineBasicBlock::iterator MBBI, Register SrcReg, 72 bool IsKill, int FrameIndex, 73 const TargetRegisterClass *RC, 74 const TargetRegisterInfo *TRI, 75 Register VReg) const override; 76 77 void loadRegFromStackSlot(MachineBasicBlock &MBB, 78 MachineBasicBlock::iterator MBBI, Register DstReg, 79 int FrameIndex, const TargetRegisterClass *RC, 80 const TargetRegisterInfo *TRI, 81 Register VReg) const override; 82 83 using TargetInstrInfo::foldMemoryOperandImpl; 84 MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, 85 ArrayRef<unsigned> Ops, 86 MachineBasicBlock::iterator InsertPt, 87 int FrameIndex, 88 LiveIntervals *LIS = nullptr, 89 VirtRegMap *VRM = nullptr) const override; 90 91 // Materializes the given integer Val into DstReg. 92 void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 93 const DebugLoc &DL, Register DstReg, uint64_t Val, 94 MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const; 95 96 unsigned getInstSizeInBytes(const MachineInstr &MI) const override; 97 98 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 99 MachineBasicBlock *&FBB, 100 SmallVectorImpl<MachineOperand> &Cond, 101 bool AllowModify) const override; 102 103 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 104 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, 105 const DebugLoc &dl, 106 int *BytesAdded = nullptr) const override; 107 108 void insertIndirectBranch(MachineBasicBlock &MBB, 109 MachineBasicBlock &NewDestBB, 110 MachineBasicBlock &RestoreBB, const DebugLoc &DL, 111 int64_t BrOffset, RegScavenger *RS) const override; 112 113 unsigned removeBranch(MachineBasicBlock &MBB, 114 int *BytesRemoved = nullptr) const override; 115 116 bool 117 reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; 118 119 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override; 120 121 bool isBranchOffsetInRange(unsigned BranchOpc, 122 int64_t BrOffset) const override; 123 124 bool analyzeSelect(const MachineInstr &MI, 125 SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp, 126 unsigned &FalseOp, bool &Optimizable) const override; 127 128 MachineInstr *optimizeSelect(MachineInstr &MI, 129 SmallPtrSetImpl<MachineInstr *> &SeenMIs, 130 bool) const override; 131 132 bool isAsCheapAsAMove(const MachineInstr &MI) const override; 133 134 std::optional<DestSourcePair> 135 isCopyInstrImpl(const MachineInstr &MI) const override; 136 137 bool verifyInstruction(const MachineInstr &MI, 138 StringRef &ErrInfo) const override; 139 140 bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, 141 const MachineOperand *&BaseOp, 142 int64_t &Offset, unsigned &Width, 143 const TargetRegisterInfo *TRI) const; 144 145 bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, 146 const MachineInstr &MIb) const override; 147 148 149 std::pair<unsigned, unsigned> 150 decomposeMachineOperandsTargetFlags(unsigned TF) const override; 151 152 ArrayRef<std::pair<unsigned, const char *>> 153 getSerializableDirectMachineOperandTargetFlags() const override; 154 155 // Return true if the function can safely be outlined from. 156 bool isFunctionSafeToOutlineFrom(MachineFunction &MF, 157 bool OutlineFromLinkOnceODRs) const override; 158 159 // Return true if MBB is safe to outline from, and return any target-specific 160 // information in Flags. 161 bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, 162 unsigned &Flags) const override; 163 164 bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override; 165 166 // Calculate target-specific information for a set of outlining candidates. 167 std::optional<outliner::OutlinedFunction> getOutliningCandidateInfo( 168 std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override; 169 170 // Return if/how a given MachineInstr should be outlined. 171 virtual outliner::InstrType 172 getOutliningTypeImpl(MachineBasicBlock::iterator &MBBI, 173 unsigned Flags) const override; 174 175 // Insert a custom frame for outlined functions. 176 void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, 177 const outliner::OutlinedFunction &OF) const override; 178 179 // Insert a call to an outlined function into a given basic block. 180 MachineBasicBlock::iterator 181 insertOutlinedCall(Module &M, MachineBasicBlock &MBB, 182 MachineBasicBlock::iterator &It, MachineFunction &MF, 183 outliner::Candidate &C) const override; 184 185 bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, 186 unsigned &SrcOpIdx2) const override; 187 MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI, 188 unsigned OpIdx1, 189 unsigned OpIdx2) const override; 190 191 MachineInstr *convertToThreeAddress(MachineInstr &MI, LiveVariables *LV, 192 LiveIntervals *LIS) const override; 193 194 // MIR printer helper function to annotate Operands with a comment. 195 std::string 196 createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, 197 unsigned OpIdx, 198 const TargetRegisterInfo *TRI) const override; 199 200 void getVLENFactoredAmount( 201 MachineFunction &MF, MachineBasicBlock &MBB, 202 MachineBasicBlock::iterator II, const DebugLoc &DL, Register DestReg, 203 int64_t Amount, MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const; 204 205 bool useMachineCombiner() const override { return true; } 206 207 MachineTraceStrategy getMachineCombinerTraceStrategy() const override; 208 209 void setSpecialOperandAttr(MachineInstr &OldMI1, MachineInstr &OldMI2, 210 MachineInstr &NewMI1, 211 MachineInstr &NewMI2) const override; 212 bool 213 getMachineCombinerPatterns(MachineInstr &Root, 214 SmallVectorImpl<MachineCombinerPattern> &Patterns, 215 bool DoRegPressureReduce) const override; 216 217 void 218 finalizeInsInstrs(MachineInstr &Root, MachineCombinerPattern &P, 219 SmallVectorImpl<MachineInstr *> &InsInstrs) const override; 220 221 void genAlternativeCodeSequence( 222 MachineInstr &Root, MachineCombinerPattern Pattern, 223 SmallVectorImpl<MachineInstr *> &InsInstrs, 224 SmallVectorImpl<MachineInstr *> &DelInstrs, 225 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const override; 226 227 bool hasReassociableSibling(const MachineInstr &Inst, 228 bool &Commuted) const override; 229 230 bool isAssociativeAndCommutative(const MachineInstr &Inst, 231 bool Invert) const override; 232 233 std::optional<unsigned> getInverseOpcode(unsigned Opcode) const override; 234 235 ArrayRef<std::pair<MachineMemOperand::Flags, const char *>> 236 getSerializableMachineMemOperandTargetFlags() const override; 237 238 protected: 239 const RISCVSubtarget &STI; 240 241 private: 242 unsigned getInstBundleLength(const MachineInstr &MI) const; 243 }; 244 245 namespace RISCV { 246 247 // Returns true if this is the sext.w pattern, addiw rd, rs1, 0. 248 bool isSEXT_W(const MachineInstr &MI); 249 bool isZEXT_W(const MachineInstr &MI); 250 bool isZEXT_B(const MachineInstr &MI); 251 252 // Returns true if the given MI is an RVV instruction opcode for which we may 253 // expect to see a FrameIndex operand. 254 bool isRVVSpill(const MachineInstr &MI); 255 256 std::optional<std::pair<unsigned, unsigned>> 257 isRVVSpillForZvlsseg(unsigned Opcode); 258 259 bool isFaultFirstLoad(const MachineInstr &MI); 260 261 // Implemented in RISCVGenInstrInfo.inc 262 int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex); 263 264 // Return true if both input instructions have equal rounding mode. If at least 265 // one of the instructions does not have rounding mode, false will be returned. 266 bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2); 267 268 // Special immediate for AVL operand of V pseudo instructions to indicate VLMax. 269 static constexpr int64_t VLMaxSentinel = -1LL; 270 271 // Mask assignments for floating-point 272 static constexpr unsigned FPMASK_Negative_Infinity = 0x001; 273 static constexpr unsigned FPMASK_Negative_Normal = 0x002; 274 static constexpr unsigned FPMASK_Negative_Subnormal = 0x004; 275 static constexpr unsigned FPMASK_Negative_Zero = 0x008; 276 static constexpr unsigned FPMASK_Positive_Zero = 0x010; 277 static constexpr unsigned FPMASK_Positive_Subnormal = 0x020; 278 static constexpr unsigned FPMASK_Positive_Normal = 0x040; 279 static constexpr unsigned FPMASK_Positive_Infinity = 0x080; 280 static constexpr unsigned FPMASK_Signaling_NaN = 0x100; 281 static constexpr unsigned FPMASK_Quiet_NaN = 0x200; 282 } // namespace RISCV 283 284 namespace RISCVVPseudosTable { 285 286 struct PseudoInfo { 287 uint16_t Pseudo; 288 uint16_t BaseInstr; 289 }; 290 291 #define GET_RISCVVPseudosTable_DECL 292 #include "RISCVGenSearchableTables.inc" 293 294 } // end namespace RISCVVPseudosTable 295 296 } // end namespace llvm 297 #endif 298