LLVM  16.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"
17 #include "llvm/IR/Intrinsics.h"
18 #include "llvm/Support/Debug.h"
21 using namespace llvm;
22 
23 //===--------------------------------------------------------------------===//
24 /// VEDAGToDAGISel - VE specific code to select VE machine
25 /// instructions for SelectionDAG operations.
26 ///
27 namespace {
28 class VEDAGToDAGISel : public SelectionDAGISel {
29  /// Subtarget - Keep a pointer to the VE Subtarget around so that we can
30  /// make the right decision when generating code for different targets.
31  const VESubtarget *Subtarget;
32 
33 public:
34  explicit VEDAGToDAGISel(VETargetMachine &tm) : SelectionDAGISel(tm) {}
35 
36  bool runOnMachineFunction(MachineFunction &MF) override {
37  Subtarget = &MF.getSubtarget<VESubtarget>();
39  }
40 
41  void Select(SDNode *N) override;
42 
43  // Complex Pattern Selectors.
44  bool selectADDRrri(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
45  bool selectADDRrii(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
46  bool selectADDRzri(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
47  bool selectADDRzii(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
48  bool selectADDRri(SDValue N, SDValue &Base, SDValue &Offset);
49  bool selectADDRzi(SDValue N, SDValue &Base, SDValue &Offset);
50 
51  /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
52  /// inline asm expressions.
53  bool SelectInlineAsmMemoryOperand(const SDValue &Op,
54  unsigned ConstraintID,
55  std::vector<SDValue> &OutOps) override;
56 
57  StringRef getPassName() const override {
58  return "VE DAG->DAG Pattern Instruction Selection";
59  }
60 
61  // Include the pieces autogenerated from the target description.
62 #include "VEGenDAGISel.inc"
63 
64 private:
65  SDNode *getGlobalBaseReg();
66 
67  bool matchADDRrr(SDValue N, SDValue &Base, SDValue &Index);
68  bool matchADDRri(SDValue N, SDValue &Base, SDValue &Offset);
69 };
70 } // end anonymous namespace
71 
72 bool VEDAGToDAGISel::selectADDRrri(SDValue Addr, SDValue &Base, SDValue &Index,
73  SDValue &Offset) {
74  if (Addr.getOpcode() == ISD::FrameIndex)
75  return false;
76  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
77  Addr.getOpcode() == ISD::TargetGlobalAddress ||
78  Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
79  return false; // direct calls.
80 
81  SDValue LHS, RHS;
82  if (matchADDRri(Addr, LHS, RHS)) {
83  if (matchADDRrr(LHS, Base, Index)) {
84  Offset = RHS;
85  return true;
86  }
87  // Return false to try selectADDRrii.
88  return false;
89  }
90  if (matchADDRrr(Addr, LHS, RHS)) {
91  // If the input is a pair of a frame-index and a register, move a
92  // frame-index to LHS. This generates MI with following operands.
93  // %dest, #FI, %reg, offset
94  // In the eliminateFrameIndex, above MI is converted to the following.
95  // %dest, %fp, %reg, fi_offset + offset
96  if (isa<FrameIndexSDNode>(RHS))
97  std::swap(LHS, RHS);
98 
99  if (matchADDRri(RHS, Index, Offset)) {
100  Base = LHS;
101  return true;
102  }
103  if (matchADDRri(LHS, Base, Offset)) {
104  Index = RHS;
105  return true;
106  }
107  Base = LHS;
108  Index = RHS;
109  Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
110  return true;
111  }
112  return false; // Let the reg+imm(=0) pattern catch this!
113 }
114 
115 bool VEDAGToDAGISel::selectADDRrii(SDValue Addr, SDValue &Base, SDValue &Index,
116  SDValue &Offset) {
117  if (matchADDRri(Addr, Base, Offset)) {
118  Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
119  return true;
120  }
121 
122  Base = Addr;
123  Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
124  Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
125  return true;
126 }
127 
128 bool VEDAGToDAGISel::selectADDRzri(SDValue Addr, SDValue &Base, SDValue &Index,
129  SDValue &Offset) {
130  // Prefer ADDRrii.
131  return false;
132 }
133 
134 bool VEDAGToDAGISel::selectADDRzii(SDValue Addr, SDValue &Base, SDValue &Index,
135  SDValue &Offset) {
136  if (isa<FrameIndexSDNode>(Addr))
137  return false;
138  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
139  Addr.getOpcode() == ISD::TargetGlobalAddress ||
140  Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
141  return false; // direct calls.
142 
143  if (auto *CN = dyn_cast<ConstantSDNode>(Addr)) {
144  if (isInt<32>(CN->getSExtValue())) {
145  Base = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
146  Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
147  Offset =
148  CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
149  return true;
150  }
151  }
152  return false;
153 }
154 
155 bool VEDAGToDAGISel::selectADDRri(SDValue Addr, SDValue &Base,
156  SDValue &Offset) {
157  if (matchADDRri(Addr, Base, Offset))
158  return true;
159 
160  Base = Addr;
161  Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
162  return true;
163 }
164 
165 bool VEDAGToDAGISel::selectADDRzi(SDValue Addr, SDValue &Base,
166  SDValue &Offset) {
167  if (isa<FrameIndexSDNode>(Addr))
168  return false;
169  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
170  Addr.getOpcode() == ISD::TargetGlobalAddress ||
171  Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
172  return false; // direct calls.
173 
174  if (auto *CN = dyn_cast<ConstantSDNode>(Addr)) {
175  if (isInt<32>(CN->getSExtValue())) {
176  Base = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
177  Offset =
178  CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
179  return true;
180  }
181  }
182  return false;
183 }
184 
185 bool VEDAGToDAGISel::matchADDRrr(SDValue Addr, SDValue &Base, SDValue &Index) {
186  if (isa<FrameIndexSDNode>(Addr))
187  return false;
188  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
189  Addr.getOpcode() == ISD::TargetGlobalAddress ||
190  Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
191  return false; // direct calls.
192 
193  if (Addr.getOpcode() == ISD::ADD) {
194  ; // Nothing to do here.
195  } else if (Addr.getOpcode() == ISD::OR) {
196  // We want to look through a transform in InstCombine and DAGCombiner that
197  // turns 'add' into 'or', so we can treat this 'or' exactly like an 'add'.
198  if (!CurDAG->haveNoCommonBitsSet(Addr.getOperand(0), Addr.getOperand(1)))
199  return false;
200  } else {
201  return false;
202  }
203 
204  if (Addr.getOperand(0).getOpcode() == VEISD::Lo ||
205  Addr.getOperand(1).getOpcode() == VEISD::Lo)
206  return false; // Let the LEASL patterns catch this!
207 
208  Base = Addr.getOperand(0);
209  Index = Addr.getOperand(1);
210  return true;
211 }
212 
213 bool VEDAGToDAGISel::matchADDRri(SDValue Addr, SDValue &Base, SDValue &Offset) {
214  auto AddrTy = Addr->getValueType(0);
215  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
216  Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy);
217  Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
218  return true;
219  }
220  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
221  Addr.getOpcode() == ISD::TargetGlobalAddress ||
222  Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
223  return false; // direct calls.
224 
225  if (CurDAG->isBaseWithConstantOffset(Addr)) {
226  ConstantSDNode *CN = cast<ConstantSDNode>(Addr.getOperand(1));
227  if (isInt<32>(CN->getSExtValue())) {
228  if (FrameIndexSDNode *FIN =
229  dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
230  // Constant offset from frame ref.
231  Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy);
232  } else {
233  Base = Addr.getOperand(0);
234  }
235  Offset =
236  CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
237  return true;
238  }
239  }
240  return false;
241 }
242 
244  SDLoc dl(N);
245  if (N->isMachineOpcode()) {
246  N->setNodeId(-1);
247  return; // Already selected.
248  }
249 
250  switch (N->getOpcode()) {
251 
252  // Late eliminate the LEGALAVL wrapper
253  case VEISD::LEGALAVL:
254  ReplaceNode(N, N->getOperand(0).getNode());
255  return;
256 
257  // Lower (broadcast 1) and (broadcast 0) to VM[P]0
258  case VEISD::VEC_BROADCAST: {
259  MVT SplatResTy = N->getSimpleValueType(0);
260  if (SplatResTy.getVectorElementType() != MVT::i1)
261  break;
262 
263  // Constant non-zero broadcast.
264  auto BConst = dyn_cast<ConstantSDNode>(N->getOperand(0));
265  if (!BConst)
266  break;
267  bool BCTrueMask = (BConst->getSExtValue() != 0);
268  if (!BCTrueMask)
269  break;
270 
271  // Packed or non-packed.
272  SDValue New;
273  if (SplatResTy.getVectorNumElements() == StandardVectorWidth) {
274  New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(N), VE::VM0,
275  MVT::v256i1);
276  } else if (SplatResTy.getVectorNumElements() == PackedVectorWidth) {
277  New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(N), VE::VMP0,
278  MVT::v512i1);
279  } else
280  break;
281 
282  // Replace.
283  ReplaceNode(N, New.getNode());
284  return;
285  }
286 
288  ReplaceNode(N, getGlobalBaseReg());
289  return;
290  }
291 
292  SelectCode(N);
293 }
294 
295 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
296 /// inline asm expressions.
297 bool
298 VEDAGToDAGISel::SelectInlineAsmMemoryOperand(const SDValue &Op,
299  unsigned ConstraintID,
300  std::vector<SDValue> &OutOps) {
301  SDValue Op0, Op1;
302  switch (ConstraintID) {
303  default:
304  llvm_unreachable("Unexpected asm memory constraint");
306  case InlineAsm::Constraint_m: // memory
307  // Try to match ADDRri since reg+imm style is safe for all VE instructions
308  // with a memory operand.
309  if (selectADDRri(Op, Op0, Op1)) {
310  OutOps.push_back(Op0);
311  OutOps.push_back(Op1);
312  return false;
313  }
314  // Otherwise, require the address to be in a register and immediate 0.
315  OutOps.push_back(Op);
316  OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));
317  return false;
318  }
319  return true;
320 }
321 
322 SDNode *VEDAGToDAGISel::getGlobalBaseReg() {
323  Register GlobalBaseReg = Subtarget->getInstrInfo()->getGlobalBaseReg(MF);
324  return CurDAG
325  ->getRegister(GlobalBaseReg, TLI->getPointerTy(CurDAG->getDataLayout()))
326  .getNode();
327 }
328 
329 /// createVEISelDag - This pass converts a legalized DAG into a
330 /// VE-specific DAG, ready for instruction scheduling.
331 ///
333  return new VEDAGToDAGISel(TM);
334 }
llvm::ConstantSDNode
Definition: SelectionDAGNodes.h:1581
llvm::MVT::getVectorElementType
MVT getVectorElementType() const
Definition: MachineValueType.h:533
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1105
llvm::ISD::OR
@ OR
Definition: ISDOpcodes.h:667
ErrorHandling.h
llvm::SDNode
Represents one node in the SelectionDAG.
Definition: SelectionDAGNodes.h:463
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
llvm::VEISD::LEGALAVL
@ LEGALAVL
Definition: VEISelLowering.h:61
MachineRegisterInfo.h
LHS
Value * LHS
Definition: X86PartialReduction.cpp:75
llvm::MVT::i1
@ i1
Definition: MachineValueType.h:43
llvm::VEISD::GLOBAL_BASE_REG
@ GLOBAL_BASE_REG
Definition: VEISelLowering.h:41
llvm::PPCISD::GlobalBaseReg
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
Definition: PPCISelLowering.h:157
llvm::VEISD::VEC_BROADCAST
@ VEC_BROADCAST
Definition: VEISelLowering.h:53
Intrinsics.h
llvm::dwarf::Index
Index
Definition: Dwarf.h:472
llvm::StandardVectorWidth
static const unsigned StandardVectorWidth
Definition: VE.h:468
llvm::FrameIndexSDNode
Definition: SelectionDAGNodes.h:1784
llvm::ISD::TargetGlobalAddress
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition: ISDOpcodes.h:164
llvm::InlineAsm::Constraint_m
@ Constraint_m
Definition: InlineAsm.h:259
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:657
llvm::AMDGPU::Hwreg::Offset
Offset
Definition: SIDefines.h:416
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:79
llvm::PackedVectorWidth
static const unsigned PackedVectorWidth
Definition: VE.h:469
llvm::MVT::getVectorNumElements
unsigned getVectorNumElements() const
Definition: MachineValueType.h:880
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:853
llvm::ConstantSDNode::getZExtValue
uint64_t getZExtValue() const
Definition: SelectionDAGNodes.h:1596
llvm::ISD::TargetGlobalTLSAddress
@ TargetGlobalTLSAddress
Definition: ISDOpcodes.h:165
llvm::MVT
Machine Value Type.
Definition: MachineValueType.h:31
llvm::MVT::v256i1
@ v256i1
Definition: MachineValueType.h:74
llvm::MachineFunction
Definition: MachineFunction.h:257
SelectionDAGISel.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::ms_demangle::IntrinsicFunctionKind::New
@ New
llvm::ConstantSDNode::getSExtValue
int64_t getSExtValue() const
Definition: SelectionDAGNodes.h:1597
llvm::InlineAsm::Constraint_o
@ Constraint_o
Definition: InlineAsm.h:260
llvm::createVEISelDag
FunctionPass * createVEISelDag(VETargetMachine &TM)
createVEISelDag - This pass converts a legalized DAG into a VE-specific DAG, ready for instruction sc...
Definition: VEISelDAGToDAG.cpp:332
llvm::MVT::v512i1
@ v512i1
Definition: MachineValueType.h:75
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::VETargetMachine
Definition: VETargetMachine.h:22
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:80
llvm::MCID::Select
@ Select
Definition: MCInstrDesc.h:164
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:348
llvm::ISD::TargetExternalSymbol
@ TargetExternalSymbol
Definition: ISDOpcodes.h:169
llvm::MVT::i32
@ i32
Definition: MachineValueType.h:48
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition: SelectionDAGNodes.h:145
llvm::VEISD::Lo
@ Lo
Definition: VEISelLowering.h:43
llvm::ISD::ADD
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
VE.h
llvm::SelectionDAGISel
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
Definition: SelectionDAGISel.h:41
llvm::VESubtarget
Definition: VESubtarget.h:31
N
#define N
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
VETargetMachine.h
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
raw_ostream.h
llvm::SelectionDAGISel::runOnMachineFunction
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition: SelectionDAGISel.cpp:373
Debug.h
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58