LLVM 19.0.0git
RISCVInstrInfo.h
Go to the documentation of this file.
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 "RISCV.h"
17#include "RISCVRegisterInfo.h"
20
21#define GET_INSTRINFO_HEADER
22#define GET_INSTRINFO_OPERAND_ENUM
23#include "RISCVGenInstrInfo.inc"
24#include "RISCVGenRegisterInfo.inc"
25
26namespace llvm {
27
28class RISCVSubtarget;
29
34
35namespace RISCVCC {
36
45};
46
48unsigned getBrCond(CondCode CC, bool Imm = false);
49
50} // end of namespace RISCVCC
51
52// RISCV MachineCombiner patterns
60};
61
63
64public:
66
67 MCInst getNop() const override;
68 const MCInstrDesc &getBrCond(RISCVCC::CondCode CC, bool Imm = false) const;
69
71 int &FrameIndex) const override;
72 Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex,
73 unsigned &MemBytes) const override;
75 int &FrameIndex) const override;
76 Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex,
77 unsigned &MemBytes) const override;
78
79 bool isReallyTriviallyReMaterializable(const MachineInstr &MI) const override;
80
83 MCRegister DstReg, MCRegister SrcReg, bool KillSrc,
84 const TargetRegisterClass *RegClass) const;
86 const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg,
87 bool KillSrc) const override;
88
91 bool IsKill, int FrameIndex,
92 const TargetRegisterClass *RC,
94 Register VReg) const override;
95
98 int FrameIndex, const TargetRegisterClass *RC,
100 Register VReg) const override;
101
106 int FrameIndex,
107 LiveIntervals *LIS = nullptr,
108 VirtRegMap *VRM = nullptr) const override;
109
110 // Materializes the given integer Val into DstReg.
112 const DebugLoc &DL, Register DstReg, uint64_t Val,
114 bool DstRenamable = false, bool DstIsDead = false) const;
115
116 unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
117
119 MachineBasicBlock *&FBB,
121 bool AllowModify) const override;
122
125 const DebugLoc &dl,
126 int *BytesAdded = nullptr) const override;
127
129 MachineBasicBlock &NewDestBB,
130 MachineBasicBlock &RestoreBB, const DebugLoc &DL,
131 int64_t BrOffset, RegScavenger *RS) const override;
132
134 int *BytesRemoved = nullptr) const override;
135
136 bool
138
139 bool optimizeCondBranch(MachineInstr &MI) const override;
140
141 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
142
143 bool isBranchOffsetInRange(unsigned BranchOpc,
144 int64_t BrOffset) const override;
145
146 bool analyzeSelect(const MachineInstr &MI,
147 SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp,
148 unsigned &FalseOp, bool &Optimizable) const override;
149
152 bool) const override;
153
154 bool isAsCheapAsAMove(const MachineInstr &MI) const override;
155
156 std::optional<DestSourcePair>
157 isCopyInstrImpl(const MachineInstr &MI) const override;
158
160 StringRef &ErrInfo) const override;
161
163 const MachineInstr &AddrI,
164 ExtAddrMode &AM) const override;
165
167 const ExtAddrMode &AM) const override;
168
171 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
172 const TargetRegisterInfo *TRI) const override;
173
175 int64_t Offset1, bool OffsetIsScalable1,
177 int64_t Offset2, bool OffsetIsScalable2,
178 unsigned ClusterSize,
179 unsigned NumBytes) const override;
180
182 const MachineOperand *&BaseOp,
183 int64_t &Offset, LocationSize &Width,
184 const TargetRegisterInfo *TRI) const;
185
187 const MachineInstr &MIb) const override;
188
189
190 std::pair<unsigned, unsigned>
191 decomposeMachineOperandsTargetFlags(unsigned TF) const override;
192
195
196 // Return true if the function can safely be outlined from.
198 bool OutlineFromLinkOnceODRs) const override;
199
200 // Return true if MBB is safe to outline from, and return any target-specific
201 // information in Flags.
203 unsigned &Flags) const override;
204
206
207 // Calculate target-specific information for a set of outlining candidates.
208 std::optional<outliner::OutlinedFunction> getOutliningCandidateInfo(
209 std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override;
210
211 // Return if/how a given MachineInstr should be outlined.
212 virtual outliner::InstrType
214 unsigned Flags) const override;
215
216 // Insert a custom frame for outlined functions.
218 const outliner::OutlinedFunction &OF) const override;
219
220 // Insert a call to an outlined function into a given basic block.
224 outliner::Candidate &C) const override;
225
226 std::optional<RegImmPair> isAddImmediate(const MachineInstr &MI,
227 Register Reg) const override;
228
229 bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1,
230 unsigned &SrcOpIdx2) const override;
232 unsigned OpIdx1,
233 unsigned OpIdx2) const override;
234
236 LiveIntervals *LIS) const override;
237
238 // MIR printer helper function to annotate Operands with a comment.
239 std::string
241 unsigned OpIdx,
242 const TargetRegisterInfo *TRI) const override;
243
244 /// Generate code to multiply the value in DestReg by Amt - handles all
245 /// the common optimizations for this idiom, and supports fallback for
246 /// subtargets which don't support multiply instructions.
249 Register DestReg, uint32_t Amt, MachineInstr::MIFlag Flag) const;
250
251 bool useMachineCombiner() const override { return true; }
252
254
255 CombinerObjective getCombinerObjective(unsigned Pattern) const override;
256
259 bool DoRegPressureReduce) const override;
260
261 void
262 finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern,
263 SmallVectorImpl<MachineInstr *> &InsInstrs) const override;
264
266 MachineInstr &Root, unsigned Pattern,
269 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const override;
270
271 bool hasReassociableOperands(const MachineInstr &Inst,
272 const MachineBasicBlock *MBB) const override;
273
274 bool hasReassociableSibling(const MachineInstr &Inst,
275 bool &Commuted) const override;
276
278 bool Invert) const override;
279
280 std::optional<unsigned> getInverseOpcode(unsigned Opcode) const override;
281
283 const MachineInstr &Root, unsigned Pattern,
284 std::array<unsigned, 5> &OperandIndices) const override;
285
288
289 unsigned getUndefInitOpcode(unsigned RegClassID) const override {
290 switch (RegClassID) {
291 case RISCV::VRRegClassID:
292 return RISCV::PseudoRVVInitUndefM1;
293 case RISCV::VRM2RegClassID:
294 return RISCV::PseudoRVVInitUndefM2;
295 case RISCV::VRM4RegClassID:
296 return RISCV::PseudoRVVInitUndefM4;
297 case RISCV::VRM8RegClassID:
298 return RISCV::PseudoRVVInitUndefM8;
299 default:
300 llvm_unreachable("Unexpected register class.");
301 }
302 }
303
304protected:
306
307private:
308 unsigned getInstBundleLength(const MachineInstr &MI) const;
309
310 bool isVectorAssociativeAndCommutative(const MachineInstr &MI,
311 bool Invert = false) const;
312 bool areRVVInstsReassociable(const MachineInstr &MI1,
313 const MachineInstr &MI2) const;
314 bool hasReassociableVectorSibling(const MachineInstr &Inst,
315 bool &Commuted) const;
316};
317
318namespace RISCV {
319
320// Returns true if this is the sext.w pattern, addiw rd, rs1, 0.
321bool isSEXT_W(const MachineInstr &MI);
322bool isZEXT_W(const MachineInstr &MI);
323bool isZEXT_B(const MachineInstr &MI);
324
325// Returns true if the given MI is an RVV instruction opcode for which we may
326// expect to see a FrameIndex operand.
327bool isRVVSpill(const MachineInstr &MI);
328
329std::optional<std::pair<unsigned, unsigned>>
330isRVVSpillForZvlsseg(unsigned Opcode);
331
332bool isFaultFirstLoad(const MachineInstr &MI);
333
334// Implemented in RISCVGenInstrInfo.inc
335int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex);
336
337// Return true if both input instructions have equal rounding mode. If at least
338// one of the instructions does not have rounding mode, false will be returned.
339bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2);
340
341// If \p Opcode is a .vx vector instruction, returns the lower number of bits
342// that are used from the scalar .x operand for a given \p Log2SEW. Otherwise
343// returns null.
344std::optional<unsigned> getVectorLowDemandedScalarBits(uint16_t Opcode,
345 unsigned Log2SEW);
346
347// Returns the MC opcode of RVV pseudo instruction.
348unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode);
349
350// Special immediate for AVL operand of V pseudo instructions to indicate VLMax.
351static constexpr int64_t VLMaxSentinel = -1LL;
352
353// Mask assignments for floating-point
354static constexpr unsigned FPMASK_Negative_Infinity = 0x001;
355static constexpr unsigned FPMASK_Negative_Normal = 0x002;
356static constexpr unsigned FPMASK_Negative_Subnormal = 0x004;
357static constexpr unsigned FPMASK_Negative_Zero = 0x008;
358static constexpr unsigned FPMASK_Positive_Zero = 0x010;
359static constexpr unsigned FPMASK_Positive_Subnormal = 0x020;
360static constexpr unsigned FPMASK_Positive_Normal = 0x040;
361static constexpr unsigned FPMASK_Positive_Infinity = 0x080;
362static constexpr unsigned FPMASK_Signaling_NaN = 0x100;
363static constexpr unsigned FPMASK_Quiet_NaN = 0x200;
364} // namespace RISCV
365
366namespace RISCVVPseudosTable {
367
371};
372
373#define GET_RISCVVPseudosTable_DECL
374#include "RISCVGenSearchableTables.inc"
375
376} // end namespace RISCVVPseudosTable
377
378namespace RISCV {
379
383 uint8_t MaskOpIdx;
384 uint8_t MaskAffectsResult : 1;
385};
386#define GET_RISCVMaskedPseudosTable_DECL
387#include "RISCVGenSearchableTables.inc"
388} // end namespace RISCV
389
390} // end namespace llvm
391#endif
SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
IRTranslator LLVM IR MI
unsigned const TargetRegisterInfo * TRI
unsigned Reg
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
This class represents an Operation in the Expression.
A debug info location.
Definition: DebugLoc.h:33
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
Representation of each machine instruction.
Definition: MachineInstr.h:69
Flags
Flags values. These may be or'd together.
MachineOperand class - Representation of each machine instruction operand.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
MachineInstr * convertToThreeAddress(MachineInstr &MI, LiveVariables *LV, LiveIntervals *LIS) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
std::optional< outliner::OutlinedFunction > getOutliningCandidateInfo(std::vector< outliner::Candidate > &RepeatedSequenceLocs) const override
void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DstReg, uint64_t Val, MachineInstr::MIFlag Flag=MachineInstr::NoFlags, bool DstRenamable=false, bool DstIsDead=false) const
MachineInstr * emitLdStWithAddr(MachineInstr &MemI, const ExtAddrMode &AM) const override
void mulImm(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, Register DestReg, uint32_t Amt, MachineInstr::MIFlag Flag) const
Generate code to multiply the value in DestReg by Amt - handles all the common optimizations for this...
bool isReallyTriviallyReMaterializable(const MachineInstr &MI) const override
bool isFunctionSafeToOutlineFrom(MachineFunction &MF, bool OutlineFromLinkOnceODRs) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &dl, int *BytesAdded=nullptr) const override
bool hasReassociableSibling(const MachineInstr &Inst, bool &Commuted) const override
void copyPhysRegVector(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc, const TargetRegisterClass *RegClass) const
void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< unsigned, unsigned > &InstrIdxForVirtReg) const override
const MCInstrDesc & getBrCond(RISCVCC::CondCode CC, bool Imm=false) const
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool) const override
bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg, const MachineInstr &AddrI, ExtAddrMode &AM) const override
void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset, RegScavenger *RS) const override
bool isAsCheapAsAMove(const MachineInstr &MI) const override
bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width, const TargetRegisterInfo *TRI) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc) const override
void getReassociateOperandIndices(const MachineInstr &Root, unsigned Pattern, std::array< unsigned, 5 > &OperandIndices) const override
const RISCVSubtarget & STI
bool useMachineCombiner() const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
std::optional< unsigned > getInverseOpcode(unsigned Opcode) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
MachineTraceStrategy getMachineCombinerTraceStrategy() const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
virtual outliner::InstrType getOutliningTypeImpl(MachineBasicBlock::iterator &MBBI, unsigned Flags) const override
std::optional< RegImmPair > isAddImmediate(const MachineInstr &MI, Register Reg) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
ArrayRef< std::pair< MachineMemOperand::Flags, const char * > > getSerializableMachineMemOperandTargetFlags() const override
MCInst getNop() const override
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const override
bool getMemOperandsWithOffsetWidth(const MachineInstr &MI, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, const outliner::OutlinedFunction &OF) const override
void finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs) const override
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override
bool hasReassociableOperands(const MachineInstr &Inst, const MachineBasicBlock *MBB) const override
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx, const TargetRegisterInfo *TRI) const override
bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override
bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
MachineBasicBlock::iterator insertOutlinedCall(Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, MachineFunction &MF, outliner::Candidate &C) const override
unsigned getUndefInitOpcode(unsigned RegClassID) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DstReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
CombinerObjective getCombinerObjective(unsigned Pattern) const override
bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const override
bool optimizeCondBranch(MachineInstr &MI) const override
std::optional< DestSourcePair > isCopyInstrImpl(const MachineInstr &MI) const override
bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const override
bool shouldClusterMemOps(ArrayRef< const MachineOperand * > BaseOps1, int64_t Offset1, bool OffsetIsScalable1, ArrayRef< const MachineOperand * > BaseOps2, int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize, unsigned NumBytes) const override
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:323
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
virtual MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const
Target-dependent implementation for foldMemoryOperand.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
CondCode getOppositeBranchCondition(CondCode)
unsigned getBrCond(CondCode CC, bool Imm=false)
static constexpr unsigned FPMASK_Negative_Zero
static constexpr unsigned FPMASK_Positive_Subnormal
bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2)
static constexpr unsigned FPMASK_Positive_Normal
static constexpr unsigned FPMASK_Negative_Subnormal
static constexpr unsigned FPMASK_Negative_Normal
std::optional< unsigned > getVectorLowDemandedScalarBits(uint16_t Opcode, unsigned Log2SEW)
static constexpr unsigned FPMASK_Positive_Infinity
int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex)
static constexpr unsigned FPMASK_Negative_Infinity
static constexpr unsigned FPMASK_Quiet_NaN
unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode)
bool isSEXT_W(const MachineInstr &MI)
bool isFaultFirstLoad(const MachineInstr &MI)
std::optional< std::pair< unsigned, unsigned > > isRVVSpillForZvlsseg(unsigned Opcode)
static constexpr unsigned FPMASK_Signaling_NaN
bool isZEXT_B(const MachineInstr &MI)
static constexpr unsigned FPMASK_Positive_Zero
bool isRVVSpill(const MachineInstr &MI)
static constexpr int64_t VLMaxSentinel
bool isZEXT_W(const MachineInstr &MI)
InstrType
Represents how an instruction should be mapped by the outliner.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
RISCVMachineCombinerPattern
@ SHXADD_ADD_SLLI_OP2
@ FMADD_AX
@ FMADD_XA
@ SHXADD_ADD_SLLI_OP1
MachineTraceStrategy
Strategies for selecting traces.
static const MachineMemOperand::Flags MONontemporalBit1
static const MachineMemOperand::Flags MONontemporalBit0
CombinerObjective
The combiner's goal may differ based on which pattern it is attempting to optimize.
Used to describe addressing mode similar to ExtAddrMode in CodeGenPrepare.
An individual sequence of instructions to be replaced with a call to an outlined function.
The information necessary to create an outlined function for some class of candidate.