Path: blob/main/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfo.h
35269 views
//===-- RISCVInstrInfo.h - RISC-V Instruction Information -------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains the RISC-V implementation of the TargetInstrInfo class.9//10//===----------------------------------------------------------------------===//1112#ifndef LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H13#define LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H1415#include "RISCV.h"16#include "RISCVRegisterInfo.h"17#include "llvm/CodeGen/TargetInstrInfo.h"18#include "llvm/IR/DiagnosticInfo.h"1920#define GET_INSTRINFO_HEADER21#define GET_INSTRINFO_OPERAND_ENUM22#include "RISCVGenInstrInfo.inc"23#include "RISCVGenRegisterInfo.inc"2425namespace llvm {2627class RISCVSubtarget;2829static const MachineMemOperand::Flags MONontemporalBit0 =30MachineMemOperand::MOTargetFlag1;31static const MachineMemOperand::Flags MONontemporalBit1 =32MachineMemOperand::MOTargetFlag2;3334namespace RISCVCC {3536enum CondCode {37COND_EQ,38COND_NE,39COND_LT,40COND_GE,41COND_LTU,42COND_GEU,43COND_INVALID44};4546CondCode getOppositeBranchCondition(CondCode);47unsigned getBrCond(CondCode CC, bool Imm = false);4849} // end of namespace RISCVCC5051// RISCV MachineCombiner patterns52enum RISCVMachineCombinerPattern : unsigned {53FMADD_AX = MachineCombinerPattern::TARGET_PATTERN_START,54FMADD_XA,55FMSUB,56FNMSUB,57SHXADD_ADD_SLLI_OP1,58SHXADD_ADD_SLLI_OP2,59};6061class RISCVInstrInfo : public RISCVGenInstrInfo {6263public:64explicit RISCVInstrInfo(RISCVSubtarget &STI);6566MCInst getNop() const override;67const MCInstrDesc &getBrCond(RISCVCC::CondCode CC, bool Imm = false) const;6869Register isLoadFromStackSlot(const MachineInstr &MI,70int &FrameIndex) const override;71Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex,72unsigned &MemBytes) const override;73Register isStoreToStackSlot(const MachineInstr &MI,74int &FrameIndex) const override;75Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex,76unsigned &MemBytes) const override;7778bool isReallyTriviallyReMaterializable(const MachineInstr &MI) const override;7980void copyPhysRegVector(MachineBasicBlock &MBB,81MachineBasicBlock::iterator MBBI, const DebugLoc &DL,82MCRegister DstReg, MCRegister SrcReg, bool KillSrc,83const TargetRegisterClass *RegClass) const;84void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,85const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg,86bool KillSrc) const override;8788void storeRegToStackSlot(MachineBasicBlock &MBB,89MachineBasicBlock::iterator MBBI, Register SrcReg,90bool IsKill, int FrameIndex,91const TargetRegisterClass *RC,92const TargetRegisterInfo *TRI,93Register VReg) const override;9495void loadRegFromStackSlot(MachineBasicBlock &MBB,96MachineBasicBlock::iterator MBBI, Register DstReg,97int FrameIndex, const TargetRegisterClass *RC,98const TargetRegisterInfo *TRI,99Register VReg) const override;100101using TargetInstrInfo::foldMemoryOperandImpl;102MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI,103ArrayRef<unsigned> Ops,104MachineBasicBlock::iterator InsertPt,105int FrameIndex,106LiveIntervals *LIS = nullptr,107VirtRegMap *VRM = nullptr) const override;108109// Materializes the given integer Val into DstReg.110void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,111const DebugLoc &DL, Register DstReg, uint64_t Val,112MachineInstr::MIFlag Flag = MachineInstr::NoFlags,113bool DstRenamable = false, bool DstIsDead = false) const;114115unsigned getInstSizeInBytes(const MachineInstr &MI) const override;116117bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,118MachineBasicBlock *&FBB,119SmallVectorImpl<MachineOperand> &Cond,120bool AllowModify) const override;121122unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,123MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,124const DebugLoc &dl,125int *BytesAdded = nullptr) const override;126127void insertIndirectBranch(MachineBasicBlock &MBB,128MachineBasicBlock &NewDestBB,129MachineBasicBlock &RestoreBB, const DebugLoc &DL,130int64_t BrOffset, RegScavenger *RS) const override;131132unsigned removeBranch(MachineBasicBlock &MBB,133int *BytesRemoved = nullptr) const override;134135bool136reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;137138bool optimizeCondBranch(MachineInstr &MI) const override;139140MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;141142bool isBranchOffsetInRange(unsigned BranchOpc,143int64_t BrOffset) const override;144145bool analyzeSelect(const MachineInstr &MI,146SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp,147unsigned &FalseOp, bool &Optimizable) const override;148149MachineInstr *optimizeSelect(MachineInstr &MI,150SmallPtrSetImpl<MachineInstr *> &SeenMIs,151bool) const override;152153bool isAsCheapAsAMove(const MachineInstr &MI) const override;154155std::optional<DestSourcePair>156isCopyInstrImpl(const MachineInstr &MI) const override;157158bool verifyInstruction(const MachineInstr &MI,159StringRef &ErrInfo) const override;160161bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg,162const MachineInstr &AddrI,163ExtAddrMode &AM) const override;164165MachineInstr *emitLdStWithAddr(MachineInstr &MemI,166const ExtAddrMode &AM) const override;167168bool getMemOperandsWithOffsetWidth(169const MachineInstr &MI, SmallVectorImpl<const MachineOperand *> &BaseOps,170int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,171const TargetRegisterInfo *TRI) const override;172173bool shouldClusterMemOps(ArrayRef<const MachineOperand *> BaseOps1,174int64_t Offset1, bool OffsetIsScalable1,175ArrayRef<const MachineOperand *> BaseOps2,176int64_t Offset2, bool OffsetIsScalable2,177unsigned ClusterSize,178unsigned NumBytes) const override;179180bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt,181const MachineOperand *&BaseOp,182int64_t &Offset, LocationSize &Width,183const TargetRegisterInfo *TRI) const;184185bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,186const MachineInstr &MIb) const override;187188189std::pair<unsigned, unsigned>190decomposeMachineOperandsTargetFlags(unsigned TF) const override;191192ArrayRef<std::pair<unsigned, const char *>>193getSerializableDirectMachineOperandTargetFlags() const override;194195// Return true if the function can safely be outlined from.196bool isFunctionSafeToOutlineFrom(MachineFunction &MF,197bool OutlineFromLinkOnceODRs) const override;198199// Return true if MBB is safe to outline from, and return any target-specific200// information in Flags.201bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,202unsigned &Flags) const override;203204bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override;205206// Calculate target-specific information for a set of outlining candidates.207std::optional<outliner::OutlinedFunction> getOutliningCandidateInfo(208std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override;209210// Return if/how a given MachineInstr should be outlined.211virtual outliner::InstrType212getOutliningTypeImpl(MachineBasicBlock::iterator &MBBI,213unsigned Flags) const override;214215// Insert a custom frame for outlined functions.216void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF,217const outliner::OutlinedFunction &OF) const override;218219// Insert a call to an outlined function into a given basic block.220MachineBasicBlock::iterator221insertOutlinedCall(Module &M, MachineBasicBlock &MBB,222MachineBasicBlock::iterator &It, MachineFunction &MF,223outliner::Candidate &C) const override;224225std::optional<RegImmPair> isAddImmediate(const MachineInstr &MI,226Register Reg) const override;227228bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1,229unsigned &SrcOpIdx2) const override;230MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,231unsigned OpIdx1,232unsigned OpIdx2) const override;233234MachineInstr *convertToThreeAddress(MachineInstr &MI, LiveVariables *LV,235LiveIntervals *LIS) const override;236237// MIR printer helper function to annotate Operands with a comment.238std::string239createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op,240unsigned OpIdx,241const TargetRegisterInfo *TRI) const override;242243/// Generate code to multiply the value in DestReg by Amt - handles all244/// the common optimizations for this idiom, and supports fallback for245/// subtargets which don't support multiply instructions.246void mulImm(MachineFunction &MF, MachineBasicBlock &MBB,247MachineBasicBlock::iterator II, const DebugLoc &DL,248Register DestReg, uint32_t Amt, MachineInstr::MIFlag Flag) const;249250bool useMachineCombiner() const override { return true; }251252MachineTraceStrategy getMachineCombinerTraceStrategy() const override;253254CombinerObjective getCombinerObjective(unsigned Pattern) const override;255256bool getMachineCombinerPatterns(MachineInstr &Root,257SmallVectorImpl<unsigned> &Patterns,258bool DoRegPressureReduce) const override;259260void261finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern,262SmallVectorImpl<MachineInstr *> &InsInstrs) const override;263264void genAlternativeCodeSequence(265MachineInstr &Root, unsigned Pattern,266SmallVectorImpl<MachineInstr *> &InsInstrs,267SmallVectorImpl<MachineInstr *> &DelInstrs,268DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const override;269270bool hasReassociableOperands(const MachineInstr &Inst,271const MachineBasicBlock *MBB) const override;272273bool hasReassociableSibling(const MachineInstr &Inst,274bool &Commuted) const override;275276bool isAssociativeAndCommutative(const MachineInstr &Inst,277bool Invert) const override;278279std::optional<unsigned> getInverseOpcode(unsigned Opcode) const override;280281void getReassociateOperandIndices(282const MachineInstr &Root, unsigned Pattern,283std::array<unsigned, 5> &OperandIndices) const override;284285ArrayRef<std::pair<MachineMemOperand::Flags, const char *>>286getSerializableMachineMemOperandTargetFlags() const override;287288unsigned getUndefInitOpcode(unsigned RegClassID) const override {289switch (RegClassID) {290case RISCV::VRRegClassID:291return RISCV::PseudoRVVInitUndefM1;292case RISCV::VRM2RegClassID:293return RISCV::PseudoRVVInitUndefM2;294case RISCV::VRM4RegClassID:295return RISCV::PseudoRVVInitUndefM4;296case RISCV::VRM8RegClassID:297return RISCV::PseudoRVVInitUndefM8;298default:299llvm_unreachable("Unexpected register class.");300}301}302303protected:304const RISCVSubtarget &STI;305306private:307unsigned getInstBundleLength(const MachineInstr &MI) const;308309bool isVectorAssociativeAndCommutative(const MachineInstr &MI,310bool Invert = false) const;311bool areRVVInstsReassociable(const MachineInstr &MI1,312const MachineInstr &MI2) const;313bool hasReassociableVectorSibling(const MachineInstr &Inst,314bool &Commuted) const;315};316317namespace RISCV {318319// Returns true if this is the sext.w pattern, addiw rd, rs1, 0.320bool isSEXT_W(const MachineInstr &MI);321bool isZEXT_W(const MachineInstr &MI);322bool isZEXT_B(const MachineInstr &MI);323324// Returns true if the given MI is an RVV instruction opcode for which we may325// expect to see a FrameIndex operand.326bool isRVVSpill(const MachineInstr &MI);327328std::optional<std::pair<unsigned, unsigned>>329isRVVSpillForZvlsseg(unsigned Opcode);330331bool isFaultFirstLoad(const MachineInstr &MI);332333// Implemented in RISCVGenInstrInfo.inc334int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex);335336// Return true if both input instructions have equal rounding mode. If at least337// one of the instructions does not have rounding mode, false will be returned.338bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2);339340// If \p Opcode is a .vx vector instruction, returns the lower number of bits341// that are used from the scalar .x operand for a given \p Log2SEW. Otherwise342// returns null.343std::optional<unsigned> getVectorLowDemandedScalarBits(uint16_t Opcode,344unsigned Log2SEW);345346// Returns the MC opcode of RVV pseudo instruction.347unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode);348349// Special immediate for AVL operand of V pseudo instructions to indicate VLMax.350static constexpr int64_t VLMaxSentinel = -1LL;351352// Mask assignments for floating-point353static constexpr unsigned FPMASK_Negative_Infinity = 0x001;354static constexpr unsigned FPMASK_Negative_Normal = 0x002;355static constexpr unsigned FPMASK_Negative_Subnormal = 0x004;356static constexpr unsigned FPMASK_Negative_Zero = 0x008;357static constexpr unsigned FPMASK_Positive_Zero = 0x010;358static constexpr unsigned FPMASK_Positive_Subnormal = 0x020;359static constexpr unsigned FPMASK_Positive_Normal = 0x040;360static constexpr unsigned FPMASK_Positive_Infinity = 0x080;361static constexpr unsigned FPMASK_Signaling_NaN = 0x100;362static constexpr unsigned FPMASK_Quiet_NaN = 0x200;363} // namespace RISCV364365namespace RISCVVPseudosTable {366367struct PseudoInfo {368uint16_t Pseudo;369uint16_t BaseInstr;370};371372#define GET_RISCVVPseudosTable_DECL373#include "RISCVGenSearchableTables.inc"374375} // end namespace RISCVVPseudosTable376377namespace RISCV {378379struct RISCVMaskedPseudoInfo {380uint16_t MaskedPseudo;381uint16_t UnmaskedPseudo;382uint8_t MaskOpIdx;383uint8_t ActiveElementsAffectResult : 1;384};385#define GET_RISCVMaskedPseudosTable_DECL386#include "RISCVGenSearchableTables.inc"387} // end namespace RISCV388389} // end namespace llvm390#endif391392393