LLVM 20.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 const MachineModuleInfo &MMI,
210 std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override;
211
212 // Return if/how a given MachineInstr should be outlined.
213 virtual outliner::InstrType
216 unsigned Flags) const override;
217
218 // Insert a custom frame for outlined functions.
220 const outliner::OutlinedFunction &OF) const override;
221
222 // Insert a call to an outlined function into a given basic block.
226 outliner::Candidate &C) const override;
227
228 std::optional<RegImmPair> isAddImmediate(const MachineInstr &MI,
229 Register Reg) const override;
230
231 bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1,
232 unsigned &SrcOpIdx2) const override;
234 unsigned OpIdx1,
235 unsigned OpIdx2) const override;
236
238 LiveIntervals *LIS) const override;
239
240 // MIR printer helper function to annotate Operands with a comment.
241 std::string
243 unsigned OpIdx,
244 const TargetRegisterInfo *TRI) const override;
245
246 /// Generate code to multiply the value in DestReg by Amt - handles all
247 /// the common optimizations for this idiom, and supports fallback for
248 /// subtargets which don't support multiply instructions.
251 Register DestReg, uint32_t Amt, MachineInstr::MIFlag Flag) const;
252
253 bool useMachineCombiner() const override { return true; }
254
256
257 CombinerObjective getCombinerObjective(unsigned Pattern) const override;
258
261 bool DoRegPressureReduce) const override;
262
263 void
264 finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern,
265 SmallVectorImpl<MachineInstr *> &InsInstrs) const override;
266
268 MachineInstr &Root, unsigned Pattern,
271 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const override;
272
273 bool hasReassociableOperands(const MachineInstr &Inst,
274 const MachineBasicBlock *MBB) const override;
275
276 bool hasReassociableSibling(const MachineInstr &Inst,
277 bool &Commuted) const override;
278
280 bool Invert) const override;
281
282 std::optional<unsigned> getInverseOpcode(unsigned Opcode) const override;
283
285 const MachineInstr &Root, unsigned Pattern,
286 std::array<unsigned, 5> &OperandIndices) const override;
287
290
291 unsigned getTailDuplicateSize(CodeGenOptLevel OptLevel) const override;
292
293 unsigned getUndefInitOpcode(unsigned RegClassID) const override {
294 switch (RegClassID) {
295 case RISCV::VRRegClassID:
296 return RISCV::PseudoRVVInitUndefM1;
297 case RISCV::VRM2RegClassID:
298 return RISCV::PseudoRVVInitUndefM2;
299 case RISCV::VRM4RegClassID:
300 return RISCV::PseudoRVVInitUndefM4;
301 case RISCV::VRM8RegClassID:
302 return RISCV::PseudoRVVInitUndefM8;
303 default:
304 llvm_unreachable("Unexpected register class.");
305 }
306 }
307
308protected:
310
311private:
312 unsigned getInstBundleLength(const MachineInstr &MI) const;
313
314 bool isVectorAssociativeAndCommutative(const MachineInstr &MI,
315 bool Invert = false) const;
316 bool areRVVInstsReassociable(const MachineInstr &MI1,
317 const MachineInstr &MI2) const;
318 bool hasReassociableVectorSibling(const MachineInstr &Inst,
319 bool &Commuted) const;
320};
321
322namespace RISCV {
323
324// Returns true if this is the sext.w pattern, addiw rd, rs1, 0.
325bool isSEXT_W(const MachineInstr &MI);
326bool isZEXT_W(const MachineInstr &MI);
327bool isZEXT_B(const MachineInstr &MI);
328
329// Returns true if the given MI is an RVV instruction opcode for which we may
330// expect to see a FrameIndex operand.
331bool isRVVSpill(const MachineInstr &MI);
332
333std::optional<std::pair<unsigned, unsigned>>
334isRVVSpillForZvlsseg(unsigned Opcode);
335
336bool isFaultFirstLoad(const MachineInstr &MI);
337
338// Implemented in RISCVGenInstrInfo.inc
339int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex);
340
341// Return true if both input instructions have equal rounding mode. If at least
342// one of the instructions does not have rounding mode, false will be returned.
343bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2);
344
345// If \p Opcode is a .vx vector instruction, returns the lower number of bits
346// that are used from the scalar .x operand for a given \p Log2SEW. Otherwise
347// returns null.
348std::optional<unsigned> getVectorLowDemandedScalarBits(uint16_t Opcode,
349 unsigned Log2SEW);
350
351// Returns the MC opcode of RVV pseudo instruction.
352unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode);
353
354// Special immediate for AVL operand of V pseudo instructions to indicate VLMax.
355static constexpr int64_t VLMaxSentinel = -1LL;
356
357// Mask assignments for floating-point
358static constexpr unsigned FPMASK_Negative_Infinity = 0x001;
359static constexpr unsigned FPMASK_Negative_Normal = 0x002;
360static constexpr unsigned FPMASK_Negative_Subnormal = 0x004;
361static constexpr unsigned FPMASK_Negative_Zero = 0x008;
362static constexpr unsigned FPMASK_Positive_Zero = 0x010;
363static constexpr unsigned FPMASK_Positive_Subnormal = 0x020;
364static constexpr unsigned FPMASK_Positive_Normal = 0x040;
365static constexpr unsigned FPMASK_Positive_Infinity = 0x080;
366static constexpr unsigned FPMASK_Signaling_NaN = 0x100;
367static constexpr unsigned FPMASK_Quiet_NaN = 0x200;
368} // namespace RISCV
369
370namespace RISCVVPseudosTable {
371
375};
376
377#define GET_RISCVVPseudosTable_DECL
378#include "RISCVGenSearchableTables.inc"
379
380} // end namespace RISCVVPseudosTable
381
382namespace RISCV {
383
387 uint8_t MaskOpIdx;
388};
389#define GET_RISCVMaskedPseudosTable_DECL
390#include "RISCVGenSearchableTables.inc"
391} // end namespace RISCV
392
393} // end namespace llvm
394#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.
This class contains meta information specific to a module.
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
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
unsigned getTailDuplicateSize(CodeGenOptLevel OptLevel) 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
virtual outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI, MachineBasicBlock::iterator &MBBI, unsigned Flags) const override
MachineTraceStrategy getMachineCombinerTraceStrategy() const override
unsigned getInstSizeInBytes(const MachineInstr &MI) 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::optional< outliner::OutlinedFunction > getOutliningCandidateInfo(const MachineModuleInfo &MMI, std::vector< outliner::Candidate > &RepeatedSequenceLocs) 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:346
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.
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:54
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.