LLVM 24.0.0git
RISCVISelDAGToDAG.h
Go to the documentation of this file.
1//===---- RISCVISelDAGToDAG.h - A dag to dag inst selector for RISC-V -----===//
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 defines an instruction selector for the RISC-V target.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H
14#define LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H
15
16#include "RISCV.h"
17#include "RISCVTargetMachine.h"
20
21// RISC-V specific code to select RISC-V machine instructions for
22// SelectionDAG operations.
23namespace llvm {
25 const RISCVSubtarget *Subtarget = nullptr;
26
27public:
29
33
35 Subtarget = &MF.getSubtarget<RISCVSubtarget>();
37 }
38
39 void PreprocessISelDAG() override;
40 void PostprocessISelDAG() override;
41
42 void Select(SDNode *Node) override;
43
45 InlineAsm::ConstraintCode ConstraintID,
46 std::vector<SDValue> &OutOps) override;
47
48 bool areOffsetsWithinAlignment(SDValue Addr, Align Alignment);
49
55
57 SDValue &Base, SDValue &Index, SDValue &Scale);
58
59 template <unsigned ShiftAmount>
61 SDValue Scale;
62 if (!SelectAddrRegRegScale(Addr, ShiftAmount, Base, Index, Scale))
63 return false;
64 assert(Scale->getAsZExtVal() == ShiftAmount &&
65 "ShiftAmount doesn't match!");
66 return true;
67 }
68
69 template <unsigned MaxShift>
71 SDValue &Scale) {
72 std::array<unsigned, MaxShift + 1> Amounts;
73 std::iota(Amounts.begin(), Amounts.end(), 0);
74 return SelectAddrRegRegScale(Addr, Amounts, Base, Index, Scale);
75 }
76
78 unsigned Bits, SDValue &Base, SDValue &Index,
79 SDValue &Scale);
80
81 template <unsigned ShiftAmount, unsigned Bits>
83 SDValue &Index) {
84 SDValue Scale;
85 if (!SelectAddrRegZextRegScale(Addr, ShiftAmount, Bits, Base, Index, Scale))
86 return false;
87 assert(Scale->getAsZExtVal() == ShiftAmount &&
88 "ShiftAmount doesn't match!");
89 return true;
90 }
91
92 template <unsigned MaxShift, unsigned Bits>
94 SDValue &Scale) {
95 std::array<unsigned, MaxShift + 1> Amounts;
96 std::iota(Amounts.begin(), Amounts.end(), 0);
97 return SelectAddrRegZextRegScale(Addr, Amounts, Bits, Base, Index, Scale);
98 }
99
101
106 SDValue X, unsigned Msb, unsigned Lsb);
108 SDValue X, unsigned Msb, unsigned Lsb);
110 bool tryWideningMulAcc(SDNode *Node, const SDLoc &DL);
111
112 bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt);
114 return selectShiftMask(N, Subtarget->getXLen(), ShAmt);
115 }
116 template <unsigned Size> bool selectShiftMask(SDValue N, SDValue &ShAmt) {
117 return selectShiftMask(N, Size, ShAmt);
118 }
119
120 bool selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal, SDValue &Val);
122 return selectSETCC(N, ISD::SETNE, Val);
123 }
125 return selectSETCC(N, ISD::SETEQ, Val);
126 }
127
128 bool selectSExtBits(SDValue N, unsigned Bits, SDValue &Val);
129 template <unsigned Bits> bool selectSExtBits(SDValue N, SDValue &Val) {
130 return selectSExtBits(N, Bits, Val);
131 }
132 bool selectZExtBits(SDValue N, unsigned Bits, SDValue &Val);
133 template <unsigned Bits> bool selectZExtBits(SDValue N, SDValue &Val) {
134 return selectZExtBits(N, Bits, Val);
135 }
136
137 bool selectSHXADDOp(SDValue N, unsigned ShAmt, SDValue &Val);
138 template <unsigned ShAmt> bool selectSHXADDOp(SDValue N, SDValue &Val) {
139 return selectSHXADDOp(N, ShAmt, Val);
140 }
141
142 bool selectSHXADD_UWOp(SDValue N, unsigned ShAmt, SDValue &Val);
143 template <unsigned ShAmt> bool selectSHXADD_UWOp(SDValue N, SDValue &Val) {
144 return selectSHXADD_UWOp(N, ShAmt, Val);
145 }
146
147 bool selectZExtImm32(SDValue N, SDValue &Val);
148 bool selectNegImm(SDValue N, SDValue &Val);
150
151 bool orDisjoint(const SDNode *Node) const;
152 bool hasAllNBitUsers(SDNode *Node, unsigned Bits,
153 const unsigned Depth = 0) const;
154 bool hasAllBUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 8); }
155 bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); }
156 bool hasAllWUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 32); }
157
158 bool selectSimm5Shl2(SDValue N, SDValue &Simm5, SDValue &Shl2);
159
160 bool selectVLOp(SDValue N, SDValue &VL);
161
162 bool selectVSplat(SDValue N, SDValue &SplatVal);
163 bool selectVSplatSimm5(SDValue N, SDValue &SplatVal);
164 bool selectVSplatUimm(SDValue N, unsigned Bits, SDValue &SplatVal);
165 template <unsigned Bits> bool selectVSplatUimmBits(SDValue N, SDValue &Val) {
166 return selectVSplatUimm(N, Bits, Val);
167 }
168 bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal);
171 bool selectVSplatImm64Neg(SDValue N, SDValue &SplatVal);
172 // Matches the splat of a value which can be extended or truncated, such that
173 // only the bottom 8 bits are preserved.
174 bool selectLow8BitsVSplat(SDValue N, SDValue &SplatVal);
176
177 bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm);
178 template <unsigned Width> bool selectRVVSimm5(SDValue N, SDValue &Imm) {
179 return selectRVVSimm5(N, Width, Imm);
180 }
181
182 bool selectVMNOTOp(SDValue N, SDValue &Res);
183 bool selectVMNOT_VLOp(SDNode *Parent, SDValue N, SDValue &Res);
184
185 void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm,
186 const SDLoc &DL, unsigned CurOp,
187 bool IsMasked, bool IsStridedOrIndexed,
188 SmallVectorImpl<SDValue> &Operands,
189 bool IsLoad = false, MVT *IndexVT = nullptr);
190
191 void selectVLSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsStrided);
192 void selectVLSEGFF(SDNode *Node, unsigned NF, bool IsMasked);
193 void selectVLXSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsOrdered);
194 void selectVSSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsStrided);
195 void selectVSXSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsOrdered);
196
199
201
202 // Return the RISC-V condition code that matches the given DAG integer
203 // condition code. The CondCode must be one of those supported by the RISC-V
204 // ISA (see translateSetCCForBranch).
206 switch (CC) {
207 default:
208 llvm_unreachable("Unsupported CondCode");
209 case ISD::SETEQ:
210 return RISCVCC::COND_EQ;
211 case ISD::SETNE:
212 return RISCVCC::COND_NE;
213 case ISD::SETLT:
214 return RISCVCC::COND_LT;
215 case ISD::SETGE:
216 return RISCVCC::COND_GE;
217 case ISD::SETULT:
218 return RISCVCC::COND_LTU;
219 case ISD::SETUGE:
220 return RISCVCC::COND_GEU;
221 }
222 }
223
224// Include the pieces autogenerated from the target description.
225#define GET_DAGISEL_DECL
226#include "RISCVGenDAGISel.inc"
227
228private:
229 bool doPeepholeSExtW(SDNode *Node);
230 bool doPeepholeMaskedRVV(MachineSDNode *Node);
231 bool doPeepholeNoRegPassThru();
232 bool performCombineVMergeAndVOps(SDNode *N);
233 bool selectImm64IfCheaper(int64_t Imm, int64_t OrigImm, SDValue N,
234 SDValue &Val);
235};
236
238public:
239 static char ID;
241 CodeGenOptLevel OptLevel);
242};
243
244} // namespace llvm
245
246#endif
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Machine Value Type.
RISCVDAGToDAGISelLegacy(RISCVTargetMachine &TargetMachine, CodeGenOptLevel OptLevel)
bool selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal, SDValue &Val)
RISC-V doesn't have general instructions for integer setne/seteq, but we can check for equality with ...
bool selectSExtBits(SDValue N, unsigned Bits, SDValue &Val)
bool selectNegImm(SDValue N, SDValue &Val)
bool selectSHXADD_UWOp(SDValue N, SDValue &Val)
bool selectZExtBits(SDValue N, unsigned Bits, SDValue &Val)
bool selectSHXADD_UWOp(SDValue N, unsigned ShAmt, SDValue &Val)
Look for various patterns that can be done with a SHL that can be folded into a SHXADD_UW.
bool areOffsetsWithinAlignment(SDValue Addr, Align Alignment)
bool hasAllNBitUsers(SDNode *Node, unsigned Bits, const unsigned Depth=0) const
bool selectVSplatUimmBits(SDValue N, SDValue &Val)
bool SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base, SDValue &Offset)
Similar to SelectAddrRegImm, except that the least significant 5 bits of Offset should be all zeros.
bool SelectAddrRegZextRegFixedScale(SDValue Addr, SDValue &Base, SDValue &Index)
bool selectZExtImm32(SDValue N, SDValue &Val)
bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt)
bool SelectAddrRegReg(SDValue Addr, SDValue &Base, SDValue &Offset)
bool selectVMNOT_VLOp(SDNode *Parent, SDValue N, SDValue &Res)
bool selectSETEQ(SDValue N, SDValue &Val)
void selectVSXSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsOrdered)
RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine, CodeGenOptLevel OptLevel)
void selectVLSEGFF(SDNode *Node, unsigned NF, bool IsMasked)
bool selectVSplatSimm5Plus1NoDec(SDValue N, SDValue &SplatVal)
bool SelectAddrRegImm26(SDValue Addr, SDValue &Base, SDValue &Offset)
Similar to SelectAddrRegImm, except that the offset is a 26-bit signed immediate.
bool selectSimm5Shl2(SDValue N, SDValue &Simm5, SDValue &Shl2)
void selectSF_VC_X_SE(SDNode *Node)
bool orDisjoint(const SDNode *Node) const
bool tryWideningMulAcc(SDNode *Node, const SDLoc &DL)
bool selectLow8BitsVSplat(SDValue N, SDValue &SplatVal)
bool hasAllHUsers(SDNode *Node) const
bool SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, std::vector< SDValue > &OutOps) override
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
bool selectVSplatSimm5(SDValue N, SDValue &SplatVal)
bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm)
bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset)
bool tryUnsignedBitfieldInsertInZero(SDNode *Node, const SDLoc &DL, MVT VT, SDValue X, unsigned Msb, unsigned Lsb)
bool hasAllWUsers(SDNode *Node) const
void PreprocessISelDAG() override
PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts...
bool runOnMachineFunction(MachineFunction &MF) override
bool selectInvLogicImm(SDValue N, SDValue &Val)
bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset)
bool SelectAddrRegRegScale(SDValue Addr, ArrayRef< unsigned > Amounts, SDValue &Base, SDValue &Index, SDValue &Scale)
bool selectSExtBits(SDValue N, SDValue &Val)
bool SelectAddrRegRegFixedScale(SDValue Addr, SDValue &Base, SDValue &Index)
void selectXSfmmVSET(SDNode *Node)
bool trySignedBitfieldInsertInSign(SDNode *Node)
bool selectVSplat(SDValue N, SDValue &SplatVal)
void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm, const SDLoc &DL, unsigned CurOp, bool IsMasked, bool IsStridedOrIndexed, SmallVectorImpl< SDValue > &Operands, bool IsLoad=false, MVT *IndexVT=nullptr)
void PostprocessISelDAG() override
PostprocessISelDAG() - This hook allows the target to hack on the graph right after selection.
bool SelectAddrRegImm9(SDValue Addr, SDValue &Base, SDValue &Offset)
Similar to SelectAddrRegImm, except that the offset is restricted to uimm9.
bool selectScalarFPAsInt(SDValue N, SDValue &Imm)
bool hasAllBUsers(SDNode *Node) const
void selectVLSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsStrided)
bool tryShrinkShlLogicImm(SDNode *Node)
bool selectSETNE(SDValue N, SDValue &Val)
bool SelectAddrRegRegScale(SDValue Addr, SDValue &Base, SDValue &Index, SDValue &Scale)
void selectVSETVLI(SDNode *Node)
bool selectVLOp(SDValue N, SDValue &VL)
bool trySignedBitfieldExtract(SDNode *Node)
bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal)
bool selectRVVSimm5(SDValue N, SDValue &Imm)
bool SelectAddrRegZextRegScale(SDValue Addr, ArrayRef< unsigned > Amounts, unsigned Bits, SDValue &Base, SDValue &Index, SDValue &Scale)
bool selectVMNOTOp(SDValue N, SDValue &Res)
void selectVSSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsStrided)
bool selectVSplatImm64Neg(SDValue N, SDValue &SplatVal)
bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal)
bool SelectAddrRegZextRegScale(SDValue Addr, SDValue &Base, SDValue &Index, SDValue &Scale)
bool selectSHXADDOp(SDValue N, SDValue &Val)
bool selectShiftMask(SDValue N, SDValue &ShAmt)
bool tryUnsignedBitfieldExtract(SDNode *Node, const SDLoc &DL, MVT VT, SDValue X, unsigned Msb, unsigned Lsb)
bool selectZExtBits(SDValue N, SDValue &Val)
void selectVLXSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsOrdered)
bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt)
bool selectSHXADDOp(SDValue N, unsigned ShAmt, SDValue &Val)
Look for various patterns that can be done with a SHL that can be folded into a SHXADD.
bool tryIndexedLoad(SDNode *Node)
static RISCVCC::CondCode getRISCVCCForIntCC(ISD::CondCode CC)
bool selectVSplatUimm(SDValue N, unsigned Bits, SDValue &SplatVal)
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SelectionDAGISelLegacy(char &ID, std::unique_ptr< SelectionDAGISel > S)
SelectionDAGISel(TargetMachine &tm, CodeGenOptLevel OL=CodeGenOptLevel::Default)
virtual bool runOnMachineFunction(MachineFunction &mf)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Primary interface to the complete machine description for the target machine.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:578
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:149
DWARFExpression::Operation Op
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39