brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.6 KiB · 0ffe015 Raw
430 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the RISC-V implementation of the TargetInstrInfo class.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H14#define LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H15 16#include "RISCV.h"17#include "RISCVRegisterInfo.h"18#include "llvm/CodeGen/TargetInstrInfo.h"19#include "llvm/IR/DiagnosticInfo.h"20 21#define GET_INSTRINFO_HEADER22#define GET_INSTRINFO_OPERAND_ENUM23#include "RISCVGenInstrInfo.inc"24#include "RISCVGenRegisterInfo.inc"25 26namespace llvm {27 28// If Value is of the form C1<<C2, where C1 = 3, 5 or 9,29// returns log2(C1 - 1) and assigns Shift = C2.30// Otherwise, returns 0.31template <typename T> int isShifted359(T Value, int &Shift) {32  if (Value == 0)33    return 0;34  Shift = llvm::countr_zero(Value);35  switch (Value >> Shift) {36  case 3:37    return 1;38  case 5:39    return 2;40  case 9:41    return 3;42  default:43    return 0;44  }45}46 47class RISCVSubtarget;48 49static const MachineMemOperand::Flags MONontemporalBit0 =50    MachineMemOperand::MOTargetFlag1;51static const MachineMemOperand::Flags MONontemporalBit1 =52    MachineMemOperand::MOTargetFlag2;53 54namespace RISCVCC {55 56enum CondCode {57  COND_EQ,58  COND_NE,59  COND_LT,60  COND_GE,61  COND_LTU,62  COND_GEU,63  COND_INVALID64};65 66CondCode getInverseBranchCondition(CondCode);67unsigned getBrCond(CondCode CC, unsigned SelectOpc = 0);68 69} // end of namespace RISCVCC70 71// RISCV MachineCombiner patterns72enum RISCVMachineCombinerPattern : unsigned {73  FMADD_AX = MachineCombinerPattern::TARGET_PATTERN_START,74  FMADD_XA,75  FMSUB,76  FNMSUB,77  SHXADD_ADD_SLLI_OP1,78  SHXADD_ADD_SLLI_OP2,79};80 81class RISCVInstrInfo : public RISCVGenInstrInfo {82  const RISCVRegisterInfo RegInfo;83 84public:85  explicit RISCVInstrInfo(const RISCVSubtarget &STI);86 87  const RISCVRegisterInfo &getRegisterInfo() const { return RegInfo; }88 89  MCInst getNop() const override;90 91  Register isLoadFromStackSlot(const MachineInstr &MI,92                               int &FrameIndex) const override;93  Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex,94                               TypeSize &MemBytes) const override;95  Register isStoreToStackSlot(const MachineInstr &MI,96                              int &FrameIndex) const override;97  Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex,98                              TypeSize &MemBytes) const override;99 100  bool isReMaterializableImpl(const MachineInstr &MI) const override;101 102  bool shouldBreakCriticalEdgeToSink(MachineInstr &MI) const override {103    return MI.getOpcode() == RISCV::ADDI && MI.getOperand(1).isReg() &&104           MI.getOperand(1).getReg() == RISCV::X0;105  }106 107  void copyPhysRegVector(MachineBasicBlock &MBB,108                         MachineBasicBlock::iterator MBBI, const DebugLoc &DL,109                         MCRegister DstReg, MCRegister SrcReg, bool KillSrc,110                         const TargetRegisterClass *RegClass) const;111  void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,112                   const DebugLoc &DL, Register DstReg, Register SrcReg,113                   bool KillSrc, bool RenamableDest = false,114                   bool RenamableSrc = false) const override;115 116  void storeRegToStackSlot(117      MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg,118      bool IsKill, int FrameIndex, const TargetRegisterClass *RC,119 120      Register VReg,121      MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;122 123  void loadRegFromStackSlot(124      MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DstReg,125      int FrameIndex, const TargetRegisterClass *RC, Register VReg,126      MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;127 128  using TargetInstrInfo::foldMemoryOperandImpl;129  MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI,130                                      ArrayRef<unsigned> Ops,131                                      MachineBasicBlock::iterator InsertPt,132                                      int FrameIndex,133                                      LiveIntervals *LIS = nullptr,134                                      VirtRegMap *VRM = nullptr) const override;135 136  // Materializes the given integer Val into DstReg.137  void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,138              const DebugLoc &DL, Register DstReg, uint64_t Val,139              MachineInstr::MIFlag Flag = MachineInstr::NoFlags,140              bool DstRenamable = false, bool DstIsDead = false) const;141 142  unsigned getInstSizeInBytes(const MachineInstr &MI) const override;143 144  bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,145                     MachineBasicBlock *&FBB,146                     SmallVectorImpl<MachineOperand> &Cond,147                     bool AllowModify) const override;148 149  unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,150                        MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,151                        const DebugLoc &dl,152                        int *BytesAdded = nullptr) const override;153 154  void insertIndirectBranch(MachineBasicBlock &MBB,155                            MachineBasicBlock &NewDestBB,156                            MachineBasicBlock &RestoreBB, const DebugLoc &DL,157                            int64_t BrOffset, RegScavenger *RS) const override;158 159  unsigned removeBranch(MachineBasicBlock &MBB,160                        int *BytesRemoved = nullptr) const override;161 162  bool163  reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;164 165  bool optimizeCondBranch(MachineInstr &MI) const override;166 167  MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;168 169  bool isBranchOffsetInRange(unsigned BranchOpc,170                             int64_t BrOffset) const override;171 172  bool analyzeSelect(const MachineInstr &MI,173                     SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp,174                     unsigned &FalseOp, bool &Optimizable) const override;175 176  MachineInstr *optimizeSelect(MachineInstr &MI,177                               SmallPtrSetImpl<MachineInstr *> &SeenMIs,178                               bool) const override;179 180  bool isAsCheapAsAMove(const MachineInstr &MI) const override;181 182  std::optional<DestSourcePair>183  isCopyInstrImpl(const MachineInstr &MI) const override;184 185  bool verifyInstruction(const MachineInstr &MI,186                         StringRef &ErrInfo) const override;187 188  bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg,189                           const MachineInstr &AddrI,190                           ExtAddrMode &AM) const override;191 192  MachineInstr *emitLdStWithAddr(MachineInstr &MemI,193                                 const ExtAddrMode &AM) const override;194 195  bool getMemOperandsWithOffsetWidth(196      const MachineInstr &MI, SmallVectorImpl<const MachineOperand *> &BaseOps,197      int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,198      const TargetRegisterInfo *TRI) const override;199 200  bool shouldClusterMemOps(ArrayRef<const MachineOperand *> BaseOps1,201                           int64_t Offset1, bool OffsetIsScalable1,202                           ArrayRef<const MachineOperand *> BaseOps2,203                           int64_t Offset2, bool OffsetIsScalable2,204                           unsigned ClusterSize,205                           unsigned NumBytes) const override;206 207  bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt,208                                    const MachineOperand *&BaseOp,209                                    int64_t &Offset, LocationSize &Width,210                                    const TargetRegisterInfo *TRI) const;211 212  bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,213                                       const MachineInstr &MIb) const override;214 215 216  std::pair<unsigned, unsigned>217  decomposeMachineOperandsTargetFlags(unsigned TF) const override;218 219  ArrayRef<std::pair<unsigned, const char *>>220  getSerializableDirectMachineOperandTargetFlags() const override;221 222  // Return true if the function can safely be outlined from.223  bool isFunctionSafeToOutlineFrom(MachineFunction &MF,224                                   bool OutlineFromLinkOnceODRs) const override;225 226  // Return true if MBB is safe to outline from, and return any target-specific227  // information in Flags.228  bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,229                              unsigned &Flags) const override;230 231  bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override;232 233  // Calculate target-specific information for a set of outlining candidates.234  std::optional<std::unique_ptr<outliner::OutlinedFunction>>235  getOutliningCandidateInfo(236      const MachineModuleInfo &MMI,237      std::vector<outliner::Candidate> &RepeatedSequenceLocs,238      unsigned MinRepeats) const override;239 240  // Return if/how a given MachineInstr should be outlined.241  outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI,242                                           MachineBasicBlock::iterator &MBBI,243                                           unsigned Flags) const override;244 245  // Insert a custom frame for outlined functions.246  void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF,247                          const outliner::OutlinedFunction &OF) const override;248 249  // Insert a call to an outlined function into a given basic block.250  MachineBasicBlock::iterator251  insertOutlinedCall(Module &M, MachineBasicBlock &MBB,252                     MachineBasicBlock::iterator &It, MachineFunction &MF,253                     outliner::Candidate &C) const override;254 255  std::optional<RegImmPair> isAddImmediate(const MachineInstr &MI,256                                           Register Reg) const override;257 258  bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1,259                             unsigned &SrcOpIdx2) const override;260  MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,261                                       unsigned OpIdx1,262                                       unsigned OpIdx2) const override;263 264  bool simplifyInstruction(MachineInstr &MI) const override;265 266  MachineInstr *convertToThreeAddress(MachineInstr &MI, LiveVariables *LV,267                                      LiveIntervals *LIS) const override;268 269  // MIR printer helper function to annotate Operands with a comment.270  std::string271  createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op,272                          unsigned OpIdx,273                          const TargetRegisterInfo *TRI) const override;274 275  /// Generate code to multiply the value in DestReg by Amt - handles all276  /// the common optimizations for this idiom, and supports fallback for277  /// subtargets which don't support multiply instructions.278  void mulImm(MachineFunction &MF, MachineBasicBlock &MBB,279              MachineBasicBlock::iterator II, const DebugLoc &DL,280              Register DestReg, uint32_t Amt, MachineInstr::MIFlag Flag) const;281 282  bool useMachineCombiner() const override { return true; }283 284  MachineTraceStrategy getMachineCombinerTraceStrategy() const override;285 286  CombinerObjective getCombinerObjective(unsigned Pattern) const override;287 288  bool getMachineCombinerPatterns(MachineInstr &Root,289                                  SmallVectorImpl<unsigned> &Patterns,290                                  bool DoRegPressureReduce) const override;291 292  void293  finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern,294                    SmallVectorImpl<MachineInstr *> &InsInstrs) const override;295 296  void genAlternativeCodeSequence(297      MachineInstr &Root, unsigned Pattern,298      SmallVectorImpl<MachineInstr *> &InsInstrs,299      SmallVectorImpl<MachineInstr *> &DelInstrs,300      DenseMap<Register, unsigned> &InstrIdxForVirtReg) const override;301 302  bool hasReassociableOperands(const MachineInstr &Inst,303                               const MachineBasicBlock *MBB) const override;304 305  bool hasReassociableSibling(const MachineInstr &Inst,306                              bool &Commuted) const override;307 308  bool isAssociativeAndCommutative(const MachineInstr &Inst,309                                   bool Invert) const override;310 311  std::optional<unsigned> getInverseOpcode(unsigned Opcode) const override;312 313  void getReassociateOperandIndices(314      const MachineInstr &Root, unsigned Pattern,315      std::array<unsigned, 5> &OperandIndices) const override;316 317  ArrayRef<std::pair<MachineMemOperand::Flags, const char *>>318  getSerializableMachineMemOperandTargetFlags() const override;319 320  unsigned getTailDuplicateSize(CodeGenOptLevel OptLevel) const override;321 322  std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>323  analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override;324 325  bool isHighLatencyDef(int Opc) const override;326 327  /// Return true if pairing the given load or store may be paired with another.328  static bool isPairableLdStInstOpc(unsigned Opc);329 330  static bool isLdStSafeToPair(const MachineInstr &LdSt,331                               const TargetRegisterInfo *TRI);332#define GET_INSTRINFO_HELPER_DECLS333#include "RISCVGenInstrInfo.inc"334 335  static RISCVCC::CondCode getCondFromBranchOpc(unsigned Opc);336 337  /// Return the result of the evaluation of C0 CC C1, where CC is a338  /// RISCVCC::CondCode.339  static bool evaluateCondBranch(RISCVCC::CondCode CC, int64_t C0, int64_t C1);340 341  /// Return true if the operand is a load immediate instruction and342  /// sets Imm to the immediate value.343  static bool isFromLoadImm(const MachineRegisterInfo &MRI,344                            const MachineOperand &Op, int64_t &Imm);345 346protected:347  const RISCVSubtarget &STI;348 349private:350  unsigned getInstBundleLength(const MachineInstr &MI) const;351 352  bool isVectorAssociativeAndCommutative(const MachineInstr &MI,353                                         bool Invert = false) const;354  bool areRVVInstsReassociable(const MachineInstr &MI1,355                               const MachineInstr &MI2) const;356  bool hasReassociableVectorSibling(const MachineInstr &Inst,357                                    bool &Commuted) const;358};359 360namespace RISCV {361 362// Returns true if the given MI is an RVV instruction opcode for which we may363// expect to see a FrameIndex operand.364bool isRVVSpill(const MachineInstr &MI);365 366std::optional<std::pair<unsigned, unsigned>>367isRVVSpillForZvlsseg(unsigned Opcode);368 369// Return true if both input instructions have equal rounding mode. If at least370// one of the instructions does not have rounding mode, false will be returned.371bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2);372 373// If \p Opcode is a .vx vector instruction, returns the lower number of bits374// that are used from the scalar .x operand for a given \p Log2SEW. Otherwise375// returns null.376std::optional<unsigned> getVectorLowDemandedScalarBits(unsigned Opcode,377                                                       unsigned Log2SEW);378 379// Returns the MC opcode of RVV pseudo instruction.380unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode);381 382// For a (non-pseudo) RVV instruction \p Desc and the given \p Log2SEW, returns383// the log2 EEW of the destination operand.384unsigned getDestLog2EEW(const MCInstrDesc &Desc, unsigned Log2SEW);385 386// Special immediate for AVL operand of V pseudo instructions to indicate VLMax.387static constexpr int64_t VLMaxSentinel = -1LL;388 389/// Given two VL operands, do we know that LHS <= RHS?390bool isVLKnownLE(const MachineOperand &LHS, const MachineOperand &RHS);391 392// Mask assignments for floating-point393static constexpr unsigned FPMASK_Negative_Infinity = 0x001;394static constexpr unsigned FPMASK_Negative_Normal = 0x002;395static constexpr unsigned FPMASK_Negative_Subnormal = 0x004;396static constexpr unsigned FPMASK_Negative_Zero = 0x008;397static constexpr unsigned FPMASK_Positive_Zero = 0x010;398static constexpr unsigned FPMASK_Positive_Subnormal = 0x020;399static constexpr unsigned FPMASK_Positive_Normal = 0x040;400static constexpr unsigned FPMASK_Positive_Infinity = 0x080;401static constexpr unsigned FPMASK_Signaling_NaN = 0x100;402static constexpr unsigned FPMASK_Quiet_NaN = 0x200;403} // namespace RISCV404 405namespace RISCVVPseudosTable {406 407struct PseudoInfo {408  uint16_t Pseudo;409  uint16_t BaseInstr;410};411 412#define GET_RISCVVPseudosTable_DECL413#include "RISCVGenSearchableTables.inc"414 415} // end namespace RISCVVPseudosTable416 417namespace RISCV {418 419struct RISCVMaskedPseudoInfo {420  uint16_t MaskedPseudo;421  uint16_t UnmaskedPseudo;422  uint8_t MaskOpIdx;423};424#define GET_RISCVMaskedPseudosTable_DECL425#include "RISCVGenSearchableTables.inc"426} // end namespace RISCV427 428} // end namespace llvm429#endif430