LLVM 22.0.0git
VEISelDAGToDAG.cpp
Go to the documentation of this file.
1//===-- VEISelDAGToDAG.cpp - A dag to dag inst selector for VE ------------===//
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 VE target.
10//
11//===----------------------------------------------------------------------===//
12
13#include "VE.h"
14#include "VETargetMachine.h"
17using namespace llvm;
18
19#define DEBUG_TYPE "ve-isel"
20#define PASS_NAME "VE DAG->DAG Pattern Instruction Selection"
21
22//===--------------------------------------------------------------------===//
23/// VEDAGToDAGISel - VE specific code to select VE machine
24/// instructions for SelectionDAG operations.
25///
26namespace {
27class VEDAGToDAGISel : public SelectionDAGISel {
28 /// Subtarget - Keep a pointer to the VE Subtarget around so that we can
29 /// make the right decision when generating code for different targets.
30 const VESubtarget *Subtarget;
31
32public:
33 VEDAGToDAGISel() = delete;
34
35 explicit VEDAGToDAGISel(VETargetMachine &tm) : SelectionDAGISel(tm) {}
36
37 bool runOnMachineFunction(MachineFunction &MF) override {
38 Subtarget = &MF.getSubtarget<VESubtarget>();
40 }
41
42 void Select(SDNode *N) override;
43
44 // Complex Pattern Selectors.
45 bool selectADDRrri(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
46 bool selectADDRrii(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
47 bool selectADDRzri(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
48 bool selectADDRzii(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
49 bool selectADDRri(SDValue N, SDValue &Base, SDValue &Offset);
50 bool selectADDRzi(SDValue N, SDValue &Base, SDValue &Offset);
51
52 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
53 /// inline asm expressions.
54 bool SelectInlineAsmMemoryOperand(const SDValue &Op,
55 InlineAsm::ConstraintCode ConstraintID,
56 std::vector<SDValue> &OutOps) override;
57
58 // Include the pieces autogenerated from the target description.
59#include "VEGenDAGISel.inc"
60
61private:
62 SDNode *getGlobalBaseReg();
63
64 bool matchADDRrr(SDValue N, SDValue &Base, SDValue &Index);
65 bool matchADDRri(SDValue N, SDValue &Base, SDValue &Offset);
66};
67
68class VEDAGToDAGISelLegacy : public SelectionDAGISelLegacy {
69public:
70 static char ID;
71 explicit VEDAGToDAGISelLegacy(VETargetMachine &tm)
72 : SelectionDAGISelLegacy(ID, std::make_unique<VEDAGToDAGISel>(tm)) {}
73};
74} // end anonymous namespace
75
76char VEDAGToDAGISelLegacy::ID = 0;
77
78INITIALIZE_PASS(VEDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false)
79
80bool VEDAGToDAGISel::selectADDRrri(SDValue Addr, SDValue &Base, SDValue &Index,
81 SDValue &Offset) {
82 if (Addr.getOpcode() == ISD::FrameIndex)
83 return false;
84 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
85 Addr.getOpcode() == ISD::TargetGlobalAddress ||
86 Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
87 return false; // direct calls.
88
90 if (matchADDRri(Addr, LHS, RHS)) {
91 if (matchADDRrr(LHS, Base, Index)) {
92 Offset = RHS;
93 return true;
94 }
95 // Return false to try selectADDRrii.
96 return false;
97 }
98 if (matchADDRrr(Addr, LHS, RHS)) {
99 // If the input is a pair of a frame-index and a register, move a
100 // frame-index to LHS. This generates MI with following operands.
101 // %dest, #FI, %reg, offset
102 // In the eliminateFrameIndex, above MI is converted to the following.
103 // %dest, %fp, %reg, fi_offset + offset
105 std::swap(LHS, RHS);
106
107 if (matchADDRri(RHS, Index, Offset)) {
108 Base = LHS;
109 return true;
110 }
111 if (matchADDRri(LHS, Base, Offset)) {
112 Index = RHS;
113 return true;
114 }
115 Base = LHS;
116 Index = RHS;
117 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
118 return true;
119 }
120 return false; // Let the reg+imm(=0) pattern catch this!
121}
122
123bool VEDAGToDAGISel::selectADDRrii(SDValue Addr, SDValue &Base, SDValue &Index,
124 SDValue &Offset) {
125 if (matchADDRri(Addr, Base, Offset)) {
126 Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
127 return true;
128 }
129
130 Base = Addr;
131 Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
132 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
133 return true;
134}
135
136bool VEDAGToDAGISel::selectADDRzri(SDValue Addr, SDValue &Base, SDValue &Index,
137 SDValue &Offset) {
138 // Prefer ADDRrii.
139 return false;
140}
141
142bool VEDAGToDAGISel::selectADDRzii(SDValue Addr, SDValue &Base, SDValue &Index,
143 SDValue &Offset) {
144 if (isa<FrameIndexSDNode>(Addr))
145 return false;
146 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
149 return false; // direct calls.
150
151 if (auto *CN = dyn_cast<ConstantSDNode>(Addr)) {
152 if (isInt<32>(CN->getSExtValue())) {
153 Base = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
154 Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
155 Offset =
156 CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
157 return true;
158 }
159 }
160 return false;
161}
162
163bool VEDAGToDAGISel::selectADDRri(SDValue Addr, SDValue &Base,
164 SDValue &Offset) {
165 if (matchADDRri(Addr, Base, Offset))
166 return true;
167
168 Base = Addr;
169 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
170 return true;
171}
172
173bool VEDAGToDAGISel::selectADDRzi(SDValue Addr, SDValue &Base,
174 SDValue &Offset) {
175 if (isa<FrameIndexSDNode>(Addr))
176 return false;
177 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
180 return false; // direct calls.
181
182 if (auto *CN = dyn_cast<ConstantSDNode>(Addr)) {
183 if (isInt<32>(CN->getSExtValue())) {
184 Base = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
185 Offset =
186 CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
187 return true;
188 }
189 }
190 return false;
191}
192
193bool VEDAGToDAGISel::matchADDRrr(SDValue Addr, SDValue &Base, SDValue &Index) {
194 if (isa<FrameIndexSDNode>(Addr))
195 return false;
196 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
199 return false; // direct calls.
200
201 if (Addr.getOpcode() == ISD::ADD) {
202 ; // Nothing to do here.
203 } else if (Addr.getOpcode() == ISD::OR) {
204 // We want to look through a transform in InstCombine and DAGCombiner that
205 // turns 'add' into 'or', so we can treat this 'or' exactly like an 'add'.
206 if (!CurDAG->haveNoCommonBitsSet(Addr.getOperand(0), Addr.getOperand(1)))
207 return false;
208 } else {
209 return false;
210 }
211
212 if (Addr.getOperand(0).getOpcode() == VEISD::Lo ||
213 Addr.getOperand(1).getOpcode() == VEISD::Lo)
214 return false; // Let the LEASL patterns catch this!
215
216 Base = Addr.getOperand(0);
217 Index = Addr.getOperand(1);
218 return true;
219}
220
221bool VEDAGToDAGISel::matchADDRri(SDValue Addr, SDValue &Base, SDValue &Offset) {
222 auto AddrTy = Addr->getValueType(0);
223 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
224 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy);
225 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
226 return true;
227 }
228 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
231 return false; // direct calls.
232
233 if (CurDAG->isBaseWithConstantOffset(Addr)) {
234 ConstantSDNode *CN = cast<ConstantSDNode>(Addr.getOperand(1));
235 if (isInt<32>(CN->getSExtValue())) {
236 if (FrameIndexSDNode *FIN =
238 // Constant offset from frame ref.
239 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy);
240 } else {
241 Base = Addr.getOperand(0);
242 }
243 Offset =
244 CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
245 return true;
246 }
247 }
248 return false;
249}
250
251void VEDAGToDAGISel::Select(SDNode *N) {
252 if (N->isMachineOpcode()) {
253 N->setNodeId(-1);
254 return; // Already selected.
255 }
256
257 switch (N->getOpcode()) {
258
259 // Late eliminate the LEGALAVL wrapper
260 case VEISD::LEGALAVL:
261 ReplaceNode(N, N->getOperand(0).getNode());
262 return;
263
264 // Lower (broadcast 1) and (broadcast 0) to VM[P]0
266 MVT SplatResTy = N->getSimpleValueType(0);
267 if (SplatResTy.getVectorElementType() != MVT::i1)
268 break;
269
270 // Constant non-zero broadcast.
271 auto BConst = dyn_cast<ConstantSDNode>(N->getOperand(0));
272 if (!BConst)
273 break;
274 bool BCTrueMask = (BConst->getSExtValue() != 0);
275 if (!BCTrueMask)
276 break;
277
278 // Packed or non-packed.
279 SDValue New;
280 if (SplatResTy.getVectorNumElements() == StandardVectorWidth) {
281 New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(N), VE::VM0,
282 MVT::v256i1);
283 } else if (SplatResTy.getVectorNumElements() == PackedVectorWidth) {
284 New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(N), VE::VMP0,
285 MVT::v512i1);
286 } else
287 break;
288
289 // Replace.
290 ReplaceNode(N, New.getNode());
291 return;
292 }
293
295 ReplaceNode(N, getGlobalBaseReg());
296 return;
297 }
298
299 SelectCode(N);
300}
301
302/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
303/// inline asm expressions.
304bool VEDAGToDAGISel::SelectInlineAsmMemoryOperand(
305 const SDValue &Op, InlineAsm::ConstraintCode ConstraintID,
306 std::vector<SDValue> &OutOps) {
307 SDValue Op0, Op1;
308 switch (ConstraintID) {
309 default:
310 llvm_unreachable("Unexpected asm memory constraint");
311 case InlineAsm::ConstraintCode::o:
312 case InlineAsm::ConstraintCode::m: // memory
313 // Try to match ADDRri since reg+imm style is safe for all VE instructions
314 // with a memory operand.
315 if (selectADDRri(Op, Op0, Op1)) {
316 OutOps.push_back(Op0);
317 OutOps.push_back(Op1);
318 return false;
319 }
320 // Otherwise, require the address to be in a register and immediate 0.
321 OutOps.push_back(Op);
322 OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));
323 return false;
324 }
325 return true;
326}
327
328SDNode *VEDAGToDAGISel::getGlobalBaseReg() {
330 return CurDAG
331 ->getRegister(GlobalBaseReg, TLI->getPointerTy(CurDAG->getDataLayout()))
332 .getNode();
333}
334
335/// createVEISelDag - This pass converts a legalized DAG into a
336/// VE-specific DAG, ready for instruction scheduling.
337///
339 return new VEDAGToDAGISelLegacy(TM);
340}
return SDValue()
AMDGPU Register Bank Select
#define DEBUG_TYPE
Promote Memory to Register
Definition Mem2Reg.cpp:110
if(PassOpts->AAPipeline)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
#define PASS_NAME
Value * RHS
Value * LHS
uint64_t getZExtValue() const
int64_t getSExtValue() const
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
unsigned getVectorNumElements() const
MVT getVectorElementType() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
const SDValue & getOperand(unsigned i) const
unsigned getOpcode() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual bool runOnMachineFunction(MachineFunction &mf)
Register getGlobalBaseReg(MachineFunction *MF) const
} Optimization
const VEInstrInfo * getInstrInfo() const override
Definition VESubtarget.h:51
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:259
@ TargetExternalSymbol
Definition ISDOpcodes.h:185
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition ISDOpcodes.h:180
@ TargetGlobalTLSAddress
Definition ISDOpcodes.h:181
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:174
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
FunctionPass * createVEISelDag(VETargetMachine &TM)
createVEISelDag - This pass converts a legalized DAG into a VE-specific DAG, ready for instruction sc...
static const unsigned StandardVectorWidth
Definition VE.h:379
static const unsigned PackedVectorWidth
Definition VE.h:380
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:548
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:853
#define N