1 //===-- RISCVInstrInfo.h - RISC-V Instruction Information -------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains the RISC-V implementation of the TargetInstrInfo class.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H
14 #define LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H
17 #include "RISCVRegisterInfo.h"
18 #include "llvm/CodeGen/TargetInstrInfo.h"
19 #include "llvm/IR/DiagnosticInfo.h"
21 #define GET_INSTRINFO_HEADER
22 #define GET_INSTRINFO_OPERAND_ENUM
23 #include "RISCVGenInstrInfo.inc"
24 #include "RISCVGenRegisterInfo.inc"
30 static const MachineMemOperand::Flags MONontemporalBit0
=
31 MachineMemOperand::MOTargetFlag1
;
32 static const MachineMemOperand::Flags MONontemporalBit1
=
33 MachineMemOperand::MOTargetFlag2
;
47 CondCode
getOppositeBranchCondition(CondCode
);
48 unsigned getBrCond(CondCode CC
, bool Imm
= false);
50 } // end of namespace RISCVCC
52 // RISCV MachineCombiner patterns
53 enum RISCVMachineCombinerPattern
: unsigned {
54 FMADD_AX
= MachineCombinerPattern::TARGET_PATTERN_START
,
62 class RISCVInstrInfo
: public RISCVGenInstrInfo
{
65 explicit RISCVInstrInfo(RISCVSubtarget
&STI
);
67 MCInst
getNop() const override
;
68 const MCInstrDesc
&getBrCond(RISCVCC::CondCode CC
, bool Imm
= false) const;
70 Register
isLoadFromStackSlot(const MachineInstr
&MI
,
71 int &FrameIndex
) const override
;
72 Register
isLoadFromStackSlot(const MachineInstr
&MI
, int &FrameIndex
,
73 unsigned &MemBytes
) const override
;
74 Register
isStoreToStackSlot(const MachineInstr
&MI
,
75 int &FrameIndex
) const override
;
76 Register
isStoreToStackSlot(const MachineInstr
&MI
, int &FrameIndex
,
77 unsigned &MemBytes
) const override
;
79 bool isReallyTriviallyReMaterializable(const MachineInstr
&MI
) const override
;
81 bool shouldBreakCriticalEdgeToSink(MachineInstr
&MI
) const override
{
82 return MI
.getOpcode() == RISCV::ADDI
&& MI
.getOperand(1).isReg() &&
83 MI
.getOperand(1).getReg() == RISCV::X0
;
86 void copyPhysRegVector(MachineBasicBlock
&MBB
,
87 MachineBasicBlock::iterator MBBI
, const DebugLoc
&DL
,
88 MCRegister DstReg
, MCRegister SrcReg
, bool KillSrc
,
89 const TargetRegisterClass
*RegClass
) const;
90 void copyPhysReg(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
91 const DebugLoc
&DL
, MCRegister DstReg
, MCRegister SrcReg
,
92 bool KillSrc
, bool RenamableDest
= false,
93 bool RenamableSrc
= false) const override
;
95 void storeRegToStackSlot(MachineBasicBlock
&MBB
,
96 MachineBasicBlock::iterator MBBI
, Register SrcReg
,
97 bool IsKill
, int FrameIndex
,
98 const TargetRegisterClass
*RC
,
99 const TargetRegisterInfo
*TRI
,
100 Register VReg
) const override
;
102 void loadRegFromStackSlot(MachineBasicBlock
&MBB
,
103 MachineBasicBlock::iterator MBBI
, Register DstReg
,
104 int FrameIndex
, const TargetRegisterClass
*RC
,
105 const TargetRegisterInfo
*TRI
,
106 Register VReg
) const override
;
108 using TargetInstrInfo::foldMemoryOperandImpl
;
109 MachineInstr
*foldMemoryOperandImpl(MachineFunction
&MF
, MachineInstr
&MI
,
110 ArrayRef
<unsigned> Ops
,
111 MachineBasicBlock::iterator InsertPt
,
113 LiveIntervals
*LIS
= nullptr,
114 VirtRegMap
*VRM
= nullptr) const override
;
116 // Materializes the given integer Val into DstReg.
117 void movImm(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
118 const DebugLoc
&DL
, Register DstReg
, uint64_t Val
,
119 MachineInstr::MIFlag Flag
= MachineInstr::NoFlags
,
120 bool DstRenamable
= false, bool DstIsDead
= false) const;
122 unsigned getInstSizeInBytes(const MachineInstr
&MI
) const override
;
124 bool analyzeBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*&TBB
,
125 MachineBasicBlock
*&FBB
,
126 SmallVectorImpl
<MachineOperand
> &Cond
,
127 bool AllowModify
) const override
;
129 unsigned insertBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*TBB
,
130 MachineBasicBlock
*FBB
, ArrayRef
<MachineOperand
> Cond
,
132 int *BytesAdded
= nullptr) const override
;
134 void insertIndirectBranch(MachineBasicBlock
&MBB
,
135 MachineBasicBlock
&NewDestBB
,
136 MachineBasicBlock
&RestoreBB
, const DebugLoc
&DL
,
137 int64_t BrOffset
, RegScavenger
*RS
) const override
;
139 unsigned removeBranch(MachineBasicBlock
&MBB
,
140 int *BytesRemoved
= nullptr) const override
;
143 reverseBranchCondition(SmallVectorImpl
<MachineOperand
> &Cond
) const override
;
145 bool optimizeCondBranch(MachineInstr
&MI
) const override
;
147 MachineBasicBlock
*getBranchDestBlock(const MachineInstr
&MI
) const override
;
149 bool isBranchOffsetInRange(unsigned BranchOpc
,
150 int64_t BrOffset
) const override
;
152 bool analyzeSelect(const MachineInstr
&MI
,
153 SmallVectorImpl
<MachineOperand
> &Cond
, unsigned &TrueOp
,
154 unsigned &FalseOp
, bool &Optimizable
) const override
;
156 MachineInstr
*optimizeSelect(MachineInstr
&MI
,
157 SmallPtrSetImpl
<MachineInstr
*> &SeenMIs
,
158 bool) const override
;
160 bool isAsCheapAsAMove(const MachineInstr
&MI
) const override
;
162 std::optional
<DestSourcePair
>
163 isCopyInstrImpl(const MachineInstr
&MI
) const override
;
165 bool verifyInstruction(const MachineInstr
&MI
,
166 StringRef
&ErrInfo
) const override
;
168 bool canFoldIntoAddrMode(const MachineInstr
&MemI
, Register Reg
,
169 const MachineInstr
&AddrI
,
170 ExtAddrMode
&AM
) const override
;
172 MachineInstr
*emitLdStWithAddr(MachineInstr
&MemI
,
173 const ExtAddrMode
&AM
) const override
;
175 bool getMemOperandsWithOffsetWidth(
176 const MachineInstr
&MI
, SmallVectorImpl
<const MachineOperand
*> &BaseOps
,
177 int64_t &Offset
, bool &OffsetIsScalable
, LocationSize
&Width
,
178 const TargetRegisterInfo
*TRI
) const override
;
180 bool shouldClusterMemOps(ArrayRef
<const MachineOperand
*> BaseOps1
,
181 int64_t Offset1
, bool OffsetIsScalable1
,
182 ArrayRef
<const MachineOperand
*> BaseOps2
,
183 int64_t Offset2
, bool OffsetIsScalable2
,
184 unsigned ClusterSize
,
185 unsigned NumBytes
) const override
;
187 bool getMemOperandWithOffsetWidth(const MachineInstr
&LdSt
,
188 const MachineOperand
*&BaseOp
,
189 int64_t &Offset
, LocationSize
&Width
,
190 const TargetRegisterInfo
*TRI
) const;
192 bool areMemAccessesTriviallyDisjoint(const MachineInstr
&MIa
,
193 const MachineInstr
&MIb
) const override
;
196 std::pair
<unsigned, unsigned>
197 decomposeMachineOperandsTargetFlags(unsigned TF
) const override
;
199 ArrayRef
<std::pair
<unsigned, const char *>>
200 getSerializableDirectMachineOperandTargetFlags() const override
;
202 // Return true if the function can safely be outlined from.
203 bool isFunctionSafeToOutlineFrom(MachineFunction
&MF
,
204 bool OutlineFromLinkOnceODRs
) const override
;
206 // Return true if MBB is safe to outline from, and return any target-specific
207 // information in Flags.
208 bool isMBBSafeToOutlineFrom(MachineBasicBlock
&MBB
,
209 unsigned &Flags
) const override
;
211 bool shouldOutlineFromFunctionByDefault(MachineFunction
&MF
) const override
;
213 // Calculate target-specific information for a set of outlining candidates.
214 std::optional
<std::unique_ptr
<outliner::OutlinedFunction
>>
215 getOutliningCandidateInfo(
216 const MachineModuleInfo
&MMI
,
217 std::vector
<outliner::Candidate
> &RepeatedSequenceLocs
,
218 unsigned MinRepeats
) const override
;
220 // Return if/how a given MachineInstr should be outlined.
221 virtual outliner::InstrType
222 getOutliningTypeImpl(const MachineModuleInfo
&MMI
,
223 MachineBasicBlock::iterator
&MBBI
,
224 unsigned Flags
) const override
;
226 // Insert a custom frame for outlined functions.
227 void buildOutlinedFrame(MachineBasicBlock
&MBB
, MachineFunction
&MF
,
228 const outliner::OutlinedFunction
&OF
) const override
;
230 // Insert a call to an outlined function into a given basic block.
231 MachineBasicBlock::iterator
232 insertOutlinedCall(Module
&M
, MachineBasicBlock
&MBB
,
233 MachineBasicBlock::iterator
&It
, MachineFunction
&MF
,
234 outliner::Candidate
&C
) const override
;
236 std::optional
<RegImmPair
> isAddImmediate(const MachineInstr
&MI
,
237 Register Reg
) const override
;
239 bool findCommutedOpIndices(const MachineInstr
&MI
, unsigned &SrcOpIdx1
,
240 unsigned &SrcOpIdx2
) const override
;
241 MachineInstr
*commuteInstructionImpl(MachineInstr
&MI
, bool NewMI
,
243 unsigned OpIdx2
) const override
;
245 MachineInstr
*convertToThreeAddress(MachineInstr
&MI
, LiveVariables
*LV
,
246 LiveIntervals
*LIS
) const override
;
248 // MIR printer helper function to annotate Operands with a comment.
250 createMIROperandComment(const MachineInstr
&MI
, const MachineOperand
&Op
,
252 const TargetRegisterInfo
*TRI
) const override
;
254 /// Generate code to multiply the value in DestReg by Amt - handles all
255 /// the common optimizations for this idiom, and supports fallback for
256 /// subtargets which don't support multiply instructions.
257 void mulImm(MachineFunction
&MF
, MachineBasicBlock
&MBB
,
258 MachineBasicBlock::iterator II
, const DebugLoc
&DL
,
259 Register DestReg
, uint32_t Amt
, MachineInstr::MIFlag Flag
) const;
261 bool useMachineCombiner() const override
{ return true; }
263 MachineTraceStrategy
getMachineCombinerTraceStrategy() const override
;
265 CombinerObjective
getCombinerObjective(unsigned Pattern
) const override
;
267 bool getMachineCombinerPatterns(MachineInstr
&Root
,
268 SmallVectorImpl
<unsigned> &Patterns
,
269 bool DoRegPressureReduce
) const override
;
272 finalizeInsInstrs(MachineInstr
&Root
, unsigned &Pattern
,
273 SmallVectorImpl
<MachineInstr
*> &InsInstrs
) const override
;
275 void genAlternativeCodeSequence(
276 MachineInstr
&Root
, unsigned Pattern
,
277 SmallVectorImpl
<MachineInstr
*> &InsInstrs
,
278 SmallVectorImpl
<MachineInstr
*> &DelInstrs
,
279 DenseMap
<unsigned, unsigned> &InstrIdxForVirtReg
) const override
;
281 bool hasReassociableOperands(const MachineInstr
&Inst
,
282 const MachineBasicBlock
*MBB
) const override
;
284 bool hasReassociableSibling(const MachineInstr
&Inst
,
285 bool &Commuted
) const override
;
287 bool isAssociativeAndCommutative(const MachineInstr
&Inst
,
288 bool Invert
) const override
;
290 std::optional
<unsigned> getInverseOpcode(unsigned Opcode
) const override
;
292 void getReassociateOperandIndices(
293 const MachineInstr
&Root
, unsigned Pattern
,
294 std::array
<unsigned, 5> &OperandIndices
) const override
;
296 ArrayRef
<std::pair
<MachineMemOperand::Flags
, const char *>>
297 getSerializableMachineMemOperandTargetFlags() const override
;
299 unsigned getTailDuplicateSize(CodeGenOptLevel OptLevel
) const override
;
302 const RISCVSubtarget
&STI
;
305 unsigned getInstBundleLength(const MachineInstr
&MI
) const;
307 bool isVectorAssociativeAndCommutative(const MachineInstr
&MI
,
308 bool Invert
= false) const;
309 bool areRVVInstsReassociable(const MachineInstr
&MI1
,
310 const MachineInstr
&MI2
) const;
311 bool hasReassociableVectorSibling(const MachineInstr
&Inst
,
312 bool &Commuted
) const;
317 // Returns true if this is the sext.w pattern, addiw rd, rs1, 0.
318 bool isSEXT_W(const MachineInstr
&MI
);
319 bool isZEXT_W(const MachineInstr
&MI
);
320 bool isZEXT_B(const MachineInstr
&MI
);
322 // Returns true if the given MI is an RVV instruction opcode for which we may
323 // expect to see a FrameIndex operand.
324 bool isRVVSpill(const MachineInstr
&MI
);
326 std::optional
<std::pair
<unsigned, unsigned>>
327 isRVVSpillForZvlsseg(unsigned Opcode
);
329 bool isFaultFirstLoad(const MachineInstr
&MI
);
331 // Implemented in RISCVGenInstrInfo.inc
332 int16_t getNamedOperandIdx(uint16_t Opcode
, uint16_t NamedIndex
);
334 // Return true if both input instructions have equal rounding mode. If at least
335 // one of the instructions does not have rounding mode, false will be returned.
336 bool hasEqualFRM(const MachineInstr
&MI1
, const MachineInstr
&MI2
);
338 // If \p Opcode is a .vx vector instruction, returns the lower number of bits
339 // that are used from the scalar .x operand for a given \p Log2SEW. Otherwise
341 std::optional
<unsigned> getVectorLowDemandedScalarBits(uint16_t Opcode
,
344 // Returns the MC opcode of RVV pseudo instruction.
345 unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode
);
347 // For a (non-pseudo) RVV instruction \p Desc and the given \p Log2SEW, returns
348 // the log2 EEW of the destination operand.
349 unsigned getDestLog2EEW(const MCInstrDesc
&Desc
, unsigned Log2SEW
);
351 // Special immediate for AVL operand of V pseudo instructions to indicate VLMax.
352 static constexpr int64_t VLMaxSentinel
= -1LL;
354 /// Given two VL operands, do we know that LHS <= RHS?
355 bool isVLKnownLE(const MachineOperand
&LHS
, const MachineOperand
&RHS
);
357 // Mask assignments for floating-point
358 static constexpr unsigned FPMASK_Negative_Infinity
= 0x001;
359 static constexpr unsigned FPMASK_Negative_Normal
= 0x002;
360 static constexpr unsigned FPMASK_Negative_Subnormal
= 0x004;
361 static constexpr unsigned FPMASK_Negative_Zero
= 0x008;
362 static constexpr unsigned FPMASK_Positive_Zero
= 0x010;
363 static constexpr unsigned FPMASK_Positive_Subnormal
= 0x020;
364 static constexpr unsigned FPMASK_Positive_Normal
= 0x040;
365 static constexpr unsigned FPMASK_Positive_Infinity
= 0x080;
366 static constexpr unsigned FPMASK_Signaling_NaN
= 0x100;
367 static constexpr unsigned FPMASK_Quiet_NaN
= 0x200;
370 namespace RISCVVPseudosTable
{
377 #define GET_RISCVVPseudosTable_DECL
378 #include "RISCVGenSearchableTables.inc"
380 } // end namespace RISCVVPseudosTable
384 struct RISCVMaskedPseudoInfo
{
385 uint16_t MaskedPseudo
;
386 uint16_t UnmaskedPseudo
;
389 #define GET_RISCVMaskedPseudosTable_DECL
390 #include "RISCVGenSearchableTables.inc"
391 } // end namespace RISCV
393 } // end namespace llvm