LLVM 23.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
56 bool SelectAddrRegRegScale(SDValue Addr, unsigned MaxShiftAmount,
57 SDValue &Base, SDValue &Index, SDValue &Scale);
58
59 template <unsigned MaxShift>
61 SDValue &Scale) {
62 return SelectAddrRegRegScale(Addr, MaxShift, Base, Index, Scale);
63 }
64
65 bool SelectAddrRegZextRegScale(SDValue Addr, unsigned MaxShiftAmount,
66 unsigned Bits, SDValue &Base, SDValue &Index,
67 SDValue &Scale);
68
69 template <unsigned MaxShift, unsigned Bits>
71 SDValue &Scale) {
72 return SelectAddrRegZextRegScale(Addr, MaxShift, Bits, Base, Index, Scale);
73 }
74
76
81 SDValue X, unsigned Msb, unsigned Lsb);
83 SDValue X, unsigned Msb, unsigned Lsb);
85 bool tryWideningMulAcc(SDNode *Node, const SDLoc &DL);
86
87 bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt);
89 return selectShiftMask(N, Subtarget->getXLen(), ShAmt);
90 }
91 template <unsigned Size> bool selectShiftMask(SDValue N, SDValue &ShAmt) {
92 return selectShiftMask(N, Size, ShAmt);
93 }
94
95 bool selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal, SDValue &Val);
97 return selectSETCC(N, ISD::SETNE, Val);
98 }
100 return selectSETCC(N, ISD::SETEQ, Val);
101 }
102
103 bool selectSExtBits(SDValue N, unsigned Bits, SDValue &Val);
104 template <unsigned Bits> bool selectSExtBits(SDValue N, SDValue &Val) {
105 return selectSExtBits(N, Bits, Val);
106 }
107 bool selectZExtBits(SDValue N, unsigned Bits, SDValue &Val);
108 template <unsigned Bits> bool selectZExtBits(SDValue N, SDValue &Val) {
109 return selectZExtBits(N, Bits, Val);
110 }
111
112 bool selectSHXADDOp(SDValue N, unsigned ShAmt, SDValue &Val);
113 template <unsigned ShAmt> bool selectSHXADDOp(SDValue N, SDValue &Val) {
114 return selectSHXADDOp(N, ShAmt, Val);
115 }
116
117 bool selectSHXADD_UWOp(SDValue N, unsigned ShAmt, SDValue &Val);
118 template <unsigned ShAmt> bool selectSHXADD_UWOp(SDValue N, SDValue &Val) {
119 return selectSHXADD_UWOp(N, ShAmt, Val);
120 }
121
122 bool selectZExtImm32(SDValue N, SDValue &Val);
123 bool selectNegImm(SDValue N, SDValue &Val);
125
126 bool orDisjoint(const SDNode *Node) const;
127 bool hasAllNBitUsers(SDNode *Node, unsigned Bits,
128 const unsigned Depth = 0) const;
129 bool hasAllBUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 8); }
130 bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); }
131 bool hasAllWUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 32); }
132
133 bool selectSimm5Shl2(SDValue N, SDValue &Simm5, SDValue &Shl2);
134
135 bool selectVLOp(SDValue N, SDValue &VL);
136
137 bool selectVSplat(SDValue N, SDValue &SplatVal);
138 bool selectVSplatSimm5(SDValue N, SDValue &SplatVal);
139 bool selectVSplatUimm(SDValue N, unsigned Bits, SDValue &SplatVal);
140 template <unsigned Bits> bool selectVSplatUimmBits(SDValue N, SDValue &Val) {
141 return selectVSplatUimm(N, Bits, Val);
142 }
143 bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal);
146 bool selectVSplatImm64Neg(SDValue N, SDValue &SplatVal);
147 // Matches the splat of a value which can be extended or truncated, such that
148 // only the bottom 8 bits are preserved.
149 bool selectLow8BitsVSplat(SDValue N, SDValue &SplatVal);
151
152 bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm);
153 template <unsigned Width> bool selectRVVSimm5(SDValue N, SDValue &Imm) {
154 return selectRVVSimm5(N, Width, Imm);
155 }
156
157 bool selectVMNOTOp(SDValue N, SDValue &Res);
158 bool selectVMNOT_VLOp(SDNode *Parent, SDValue N, SDValue &Res);
159
160 void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm,
161 const SDLoc &DL, unsigned CurOp,
162 bool IsMasked, bool IsStridedOrIndexed,
163 SmallVectorImpl<SDValue> &Operands,
164 bool IsLoad = false, MVT *IndexVT = nullptr);
165
166 void selectVLSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsStrided);
167 void selectVLSEGFF(SDNode *Node, unsigned NF, bool IsMasked);
168 void selectVLXSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsOrdered);
169 void selectVSSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsStrided);
170 void selectVSXSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsOrdered);
171
174
176
177 // Return the RISC-V condition code that matches the given DAG integer
178 // condition code. The CondCode must be one of those supported by the RISC-V
179 // ISA (see translateSetCCForBranch).
181 switch (CC) {
182 default:
183 llvm_unreachable("Unsupported CondCode");
184 case ISD::SETEQ:
185 return RISCVCC::COND_EQ;
186 case ISD::SETNE:
187 return RISCVCC::COND_NE;
188 case ISD::SETLT:
189 return RISCVCC::COND_LT;
190 case ISD::SETGE:
191 return RISCVCC::COND_GE;
192 case ISD::SETULT:
193 return RISCVCC::COND_LTU;
194 case ISD::SETUGE:
195 return RISCVCC::COND_GEU;
196 }
197 }
198
199// Include the pieces autogenerated from the target description.
200#define GET_DAGISEL_DECL
201#include "RISCVGenDAGISel.inc"
202
203private:
204 bool doPeepholeSExtW(SDNode *Node);
205 bool doPeepholeMaskedRVV(MachineSDNode *Node);
206 bool doPeepholeNoRegPassThru();
207 bool performCombineVMergeAndVOps(SDNode *N);
208 bool selectImm64IfCheaper(int64_t Imm, int64_t OrigImm, SDValue N,
209 SDValue &Val);
210};
211
213public:
214 static char ID;
216 CodeGenOptLevel OptLevel);
217};
218
219} // namespace llvm
220
221#endif
return SDValue()
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
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 selectZExtImm32(SDValue N, SDValue &Val)
bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt)
bool SelectAddrRegZextRegScale(SDValue Addr, unsigned MaxShiftAmount, unsigned Bits, SDValue &Base, SDValue &Index, SDValue &Scale)
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 selectSExtBits(SDValue N, SDValue &Val)
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 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)
bool SelectAddrRegRegScale(SDValue Addr, unsigned MaxShiftAmount, SDValue &Base, SDValue &Index, SDValue &Scale)
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.
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:573
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:82
DWARFExpression::Operation Op
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39