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 getUndefInitOpcode(unsigned RegClassID) const override {
292 switch (RegClassID) {
293 case RISCV::VRRegClassID:
294 return RISCV::PseudoRVVInitUndefM1;
295 case RISCV::VRM2RegClassID:
296 return RISCV::PseudoRVVInitUndefM2;
297 case RISCV::VRM4RegClassID:
298 return RISCV::PseudoRVVInitUndefM4;
299 case RISCV::VRM8RegClassID:
300 return RISCV::PseudoRVVInitUndefM8;
301 default:
302 llvm_unreachable("Unexpected register class.");
303 }
304 }
305
306protected:
308
309private:
310 unsigned getInstBundleLength(const MachineInstr &MI) const;
311
312 bool isVectorAssociativeAndCommutative(const MachineInstr &MI,
313 bool Invert = false) const;
314 bool areRVVInstsReassociable(const MachineInstr &MI1,
315 const MachineInstr &MI2) const;
316 bool hasReassociableVectorSibling(const MachineInstr &Inst,
317 bool &Commuted) const;
318};
319
320namespace RISCV {
321
322// Returns true if this is the sext.w pattern, addiw rd, rs1, 0.
323bool isSEXT_W(const MachineInstr &MI);
324bool isZEXT_W(const MachineInstr &MI);
325bool isZEXT_B(const MachineInstr &MI);
326
327// Returns true if the given MI is an RVV instruction opcode for which we may
328// expect to see a FrameIndex operand.
329bool isRVVSpill(const MachineInstr &MI);
330
331std::optional<std::pair<unsigned, unsigned>>
332isRVVSpillForZvlsseg(unsigned Opcode);
333
334bool isFaultFirstLoad(const MachineInstr &MI);
335
336// Implemented in RISCVGenInstrInfo.inc
337int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex);
338
339// Return true if both input instructions have equal rounding mode. If at least
340// one of the instructions does not have rounding mode, false will be returned.
341bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2);
342
343// If \p Opcode is a .vx vector instruction, returns the lower number of bits
344// that are used from the scalar .x operand for a given \p Log2SEW. Otherwise
345// returns null.
346std::optional<unsigned> getVectorLowDemandedScalarBits(uint16_t Opcode,
347 unsigned Log2SEW);
348
349// Returns the MC opcode of RVV pseudo instruction.
350unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode);
351
352// Special immediate for AVL operand of V pseudo instructions to indicate VLMax.
353static constexpr int64_t VLMaxSentinel = -1LL;
354
355// Mask assignments for floating-point
356static constexpr unsigned FPMASK_Negative_Infinity = 0x001;
357static constexpr unsigned FPMASK_Negative_Normal = 0x002;
358static constexpr unsigned FPMASK_Negative_Subnormal = 0x004;
359static constexpr unsigned FPMASK_Negative_Zero = 0x008;
360static constexpr unsigned FPMASK_Positive_Zero = 0x010;
361static constexpr unsigned FPMASK_Positive_Subnormal = 0x020;
362static constexpr unsigned FPMASK_Positive_Normal = 0x040;
363static constexpr unsigned FPMASK_Positive_Infinity = 0x080;
364static constexpr unsigned FPMASK_Signaling_NaN = 0x100;
365static constexpr unsigned FPMASK_Quiet_NaN = 0x200;
366} // namespace RISCV
367
368namespace RISCVVPseudosTable {
369
373};
374
375#define GET_RISCVVPseudosTable_DECL
376#include "RISCVGenSearchableTables.inc"
377
378} // end namespace RISCVVPseudosTable
379
380namespace RISCV {
381
385 uint8_t MaskOpIdx;
387};
388#define GET_RISCVMaskedPseudosTable_DECL
389#include "RISCVGenSearchableTables.inc"
390} // end namespace RISCV
391
392} // end namespace llvm
393#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
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: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.