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);
49
50} // end of namespace RISCVCC
51
52// RISCV MachineCombiner patterns
60};
61
63
64public:
66
67 MCInst getNop() const override;
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 hasReassociableSibling(const MachineInstr &Inst,
270 bool &Commuted) const override;
271
273 bool Invert) const override;
274
275 std::optional<unsigned> getInverseOpcode(unsigned Opcode) const override;
276
279
280 unsigned getUndefInitOpcode(unsigned RegClassID) const override {
281 switch (RegClassID) {
282 case RISCV::VRRegClassID:
283 return RISCV::PseudoRVVInitUndefM1;
284 case RISCV::VRM2RegClassID:
285 return RISCV::PseudoRVVInitUndefM2;
286 case RISCV::VRM4RegClassID:
287 return RISCV::PseudoRVVInitUndefM4;
288 case RISCV::VRM8RegClassID:
289 return RISCV::PseudoRVVInitUndefM8;
290 default:
291 llvm_unreachable("Unexpected register class.");
292 }
293 }
294
295protected:
297
298private:
299 unsigned getInstBundleLength(const MachineInstr &MI) const;
300};
301
302namespace RISCV {
303
304// Returns true if this is the sext.w pattern, addiw rd, rs1, 0.
305bool isSEXT_W(const MachineInstr &MI);
306bool isZEXT_W(const MachineInstr &MI);
307bool isZEXT_B(const MachineInstr &MI);
308
309// Returns true if the given MI is an RVV instruction opcode for which we may
310// expect to see a FrameIndex operand.
311bool isRVVSpill(const MachineInstr &MI);
312
313std::optional<std::pair<unsigned, unsigned>>
314isRVVSpillForZvlsseg(unsigned Opcode);
315
316bool isFaultFirstLoad(const MachineInstr &MI);
317
318// Implemented in RISCVGenInstrInfo.inc
319int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex);
320
321// Return true if both input instructions have equal rounding mode. If at least
322// one of the instructions does not have rounding mode, false will be returned.
323bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2);
324
325// If \p Opcode is a .vx vector instruction, returns the lower number of bits
326// that are used from the scalar .x operand for a given \p Log2SEW. Otherwise
327// returns null.
328std::optional<unsigned> getVectorLowDemandedScalarBits(uint16_t Opcode,
329 unsigned Log2SEW);
330
331// Returns the MC opcode of RVV pseudo instruction.
332unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode);
333
334// Special immediate for AVL operand of V pseudo instructions to indicate VLMax.
335static constexpr int64_t VLMaxSentinel = -1LL;
336
337// Mask assignments for floating-point
338static constexpr unsigned FPMASK_Negative_Infinity = 0x001;
339static constexpr unsigned FPMASK_Negative_Normal = 0x002;
340static constexpr unsigned FPMASK_Negative_Subnormal = 0x004;
341static constexpr unsigned FPMASK_Negative_Zero = 0x008;
342static constexpr unsigned FPMASK_Positive_Zero = 0x010;
343static constexpr unsigned FPMASK_Positive_Subnormal = 0x020;
344static constexpr unsigned FPMASK_Positive_Normal = 0x040;
345static constexpr unsigned FPMASK_Positive_Infinity = 0x080;
346static constexpr unsigned FPMASK_Signaling_NaN = 0x100;
347static constexpr unsigned FPMASK_Quiet_NaN = 0x200;
348} // namespace RISCV
349
350namespace RISCVVPseudosTable {
351
355};
356
357#define GET_RISCVVPseudosTable_DECL
358#include "RISCVGenSearchableTables.inc"
359
360} // end namespace RISCVVPseudosTable
361
362} // end namespace llvm
363#endif
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
IRTranslator LLVM IR MI
unsigned const TargetRegisterInfo * TRI
unsigned Reg
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...
const MCInstrDesc & getBrCond(RISCVCC::CondCode CC) const
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
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
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
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)
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.