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
81 MCRegister DstReg, MCRegister SrcReg, bool KillSrc,
82 const TargetRegisterClass *RegClass) const;
84 const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg,
85 bool KillSrc) const override;
86
89 bool IsKill, int FrameIndex,
90 const TargetRegisterClass *RC,
92 Register VReg) const override;
93
96 int FrameIndex, const TargetRegisterClass *RC,
98 Register VReg) const override;
99
104 int FrameIndex,
105 LiveIntervals *LIS = nullptr,
106 VirtRegMap *VRM = nullptr) const override;
107
108 // Materializes the given integer Val into DstReg.
110 const DebugLoc &DL, Register DstReg, uint64_t Val,
112 bool DstRenamable = false, bool DstIsDead = false) const;
113
114 unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
115
117 MachineBasicBlock *&FBB,
119 bool AllowModify) const override;
120
123 const DebugLoc &dl,
124 int *BytesAdded = nullptr) const override;
125
127 MachineBasicBlock &NewDestBB,
128 MachineBasicBlock &RestoreBB, const DebugLoc &DL,
129 int64_t BrOffset, RegScavenger *RS) const override;
130
132 int *BytesRemoved = nullptr) const override;
133
134 bool
136
137 bool optimizeCondBranch(MachineInstr &MI) const override;
138
139 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
140
141 bool isBranchOffsetInRange(unsigned BranchOpc,
142 int64_t BrOffset) const override;
143
144 bool analyzeSelect(const MachineInstr &MI,
145 SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp,
146 unsigned &FalseOp, bool &Optimizable) const override;
147
150 bool) const override;
151
152 bool isAsCheapAsAMove(const MachineInstr &MI) const override;
153
154 std::optional<DestSourcePair>
155 isCopyInstrImpl(const MachineInstr &MI) const override;
156
158 StringRef &ErrInfo) const override;
159
161 const MachineInstr &AddrI,
162 ExtAddrMode &AM) const override;
163
165 const ExtAddrMode &AM) const override;
166
169 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
170 const TargetRegisterInfo *TRI) const override;
171
173 int64_t Offset1, bool OffsetIsScalable1,
175 int64_t Offset2, bool OffsetIsScalable2,
176 unsigned ClusterSize,
177 unsigned NumBytes) const override;
178
180 const MachineOperand *&BaseOp,
181 int64_t &Offset, LocationSize &Width,
182 const TargetRegisterInfo *TRI) const;
183
185 const MachineInstr &MIb) const override;
186
187
188 std::pair<unsigned, unsigned>
189 decomposeMachineOperandsTargetFlags(unsigned TF) const override;
190
193
194 // Return true if the function can safely be outlined from.
196 bool OutlineFromLinkOnceODRs) const override;
197
198 // Return true if MBB is safe to outline from, and return any target-specific
199 // information in Flags.
201 unsigned &Flags) const override;
202
204
205 // Calculate target-specific information for a set of outlining candidates.
206 std::optional<outliner::OutlinedFunction> getOutliningCandidateInfo(
207 std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override;
208
209 // Return if/how a given MachineInstr should be outlined.
210 virtual outliner::InstrType
212 unsigned Flags) const override;
213
214 // Insert a custom frame for outlined functions.
216 const outliner::OutlinedFunction &OF) const override;
217
218 // Insert a call to an outlined function into a given basic block.
222 outliner::Candidate &C) const override;
223
224 std::optional<RegImmPair> isAddImmediate(const MachineInstr &MI,
225 Register Reg) const override;
226
227 bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1,
228 unsigned &SrcOpIdx2) const override;
230 unsigned OpIdx1,
231 unsigned OpIdx2) const override;
232
234 LiveIntervals *LIS) const override;
235
236 // MIR printer helper function to annotate Operands with a comment.
237 std::string
239 unsigned OpIdx,
240 const TargetRegisterInfo *TRI) const override;
241
242 /// Generate code to multiply the value in DestReg by Amt - handles all
243 /// the common optimizations for this idiom, and supports fallback for
244 /// subtargets which don't support multiply instructions.
247 Register DestReg, uint32_t Amt, MachineInstr::MIFlag Flag) const;
248
249 bool useMachineCombiner() const override { return true; }
250
252
253 CombinerObjective getCombinerObjective(unsigned Pattern) const override;
254
257 bool DoRegPressureReduce) const override;
258
259 void
260 finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern,
261 SmallVectorImpl<MachineInstr *> &InsInstrs) const override;
262
264 MachineInstr &Root, unsigned Pattern,
267 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const override;
268
269 bool hasReassociableOperands(const MachineInstr &Inst,
270 const MachineBasicBlock *MBB) const override;
271
272 bool hasReassociableSibling(const MachineInstr &Inst,
273 bool &Commuted) const override;
274
276 bool Invert) const override;
277
278 std::optional<unsigned> getInverseOpcode(unsigned Opcode) const override;
279
281 const MachineInstr &Root, unsigned Pattern,
282 std::array<unsigned, 5> &OperandIndices) const override;
283
286
287 unsigned getUndefInitOpcode(unsigned RegClassID) const override {
288 switch (RegClassID) {
289 case RISCV::VRRegClassID:
290 return RISCV::PseudoRVVInitUndefM1;
291 case RISCV::VRM2RegClassID:
292 return RISCV::PseudoRVVInitUndefM2;
293 case RISCV::VRM4RegClassID:
294 return RISCV::PseudoRVVInitUndefM4;
295 case RISCV::VRM8RegClassID:
296 return RISCV::PseudoRVVInitUndefM8;
297 default:
298 llvm_unreachable("Unexpected register class.");
299 }
300 }
301
302protected:
304
305private:
306 unsigned getInstBundleLength(const MachineInstr &MI) const;
307
308 bool isVectorAssociativeAndCommutative(const MachineInstr &MI,
309 bool Invert = false) const;
310 bool areRVVInstsReassociable(const MachineInstr &MI1,
311 const MachineInstr &MI2) const;
312 bool hasReassociableVectorSibling(const MachineInstr &Inst,
313 bool &Commuted) const;
314};
315
316namespace RISCV {
317
318// Returns true if this is the sext.w pattern, addiw rd, rs1, 0.
319bool isSEXT_W(const MachineInstr &MI);
320bool isZEXT_W(const MachineInstr &MI);
321bool isZEXT_B(const MachineInstr &MI);
322
323// Returns true if the given MI is an RVV instruction opcode for which we may
324// expect to see a FrameIndex operand.
325bool isRVVSpill(const MachineInstr &MI);
326
327std::optional<std::pair<unsigned, unsigned>>
328isRVVSpillForZvlsseg(unsigned Opcode);
329
330bool isFaultFirstLoad(const MachineInstr &MI);
331
332// Implemented in RISCVGenInstrInfo.inc
333int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex);
334
335// Return true if both input instructions have equal rounding mode. If at least
336// one of the instructions does not have rounding mode, false will be returned.
337bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2);
338
339// If \p Opcode is a .vx vector instruction, returns the lower number of bits
340// that are used from the scalar .x operand for a given \p Log2SEW. Otherwise
341// returns null.
342std::optional<unsigned> getVectorLowDemandedScalarBits(uint16_t Opcode,
343 unsigned Log2SEW);
344
345// Returns the MC opcode of RVV pseudo instruction.
346unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode);
347
348// Special immediate for AVL operand of V pseudo instructions to indicate VLMax.
349static constexpr int64_t VLMaxSentinel = -1LL;
350
351// Mask assignments for floating-point
352static constexpr unsigned FPMASK_Negative_Infinity = 0x001;
353static constexpr unsigned FPMASK_Negative_Normal = 0x002;
354static constexpr unsigned FPMASK_Negative_Subnormal = 0x004;
355static constexpr unsigned FPMASK_Negative_Zero = 0x008;
356static constexpr unsigned FPMASK_Positive_Zero = 0x010;
357static constexpr unsigned FPMASK_Positive_Subnormal = 0x020;
358static constexpr unsigned FPMASK_Positive_Normal = 0x040;
359static constexpr unsigned FPMASK_Positive_Infinity = 0x080;
360static constexpr unsigned FPMASK_Signaling_NaN = 0x100;
361static constexpr unsigned FPMASK_Quiet_NaN = 0x200;
362} // namespace RISCV
363
364namespace RISCVVPseudosTable {
365
369};
370
371#define GET_RISCVVPseudosTable_DECL
372#include "RISCVGenSearchableTables.inc"
373
374} // end namespace RISCVVPseudosTable
375
376namespace RISCV {
377
381 uint8_t MaskOpIdx;
382 uint8_t MaskAffectsResult : 1;
383};
384#define GET_RISCVMaskedPseudosTable_DECL
385#include "RISCVGenSearchableTables.inc"
386} // end namespace RISCV
387
388} // end namespace llvm
389#endif
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices
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 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:321
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:456
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.