LLVM  12.0.0git
RISCVISelDAGToDAG.cpp
Go to the documentation of this file.
1 //===-- RISCVISelDAGToDAG.cpp - A dag to dag inst selector for RISCV ------===//
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 RISCV target.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "RISCVISelDAGToDAG.h"
15 #include "Utils/RISCVMatInt.h"
17 #include "llvm/Support/Alignment.h"
18 #include "llvm/Support/Debug.h"
21 
22 using namespace llvm;
23 
24 #define DEBUG_TYPE "riscv-isel"
25 
27  doPeepholeLoadStoreADDI();
28 }
29 
30 static SDNode *selectImm(SelectionDAG *CurDAG, const SDLoc &DL, int64_t Imm,
31  MVT XLenVT) {
33  RISCVMatInt::generateInstSeq(Imm, XLenVT == MVT::i64, Seq);
34 
35  SDNode *Result = nullptr;
36  SDValue SrcReg = CurDAG->getRegister(RISCV::X0, XLenVT);
37  for (RISCVMatInt::Inst &Inst : Seq) {
38  SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm, DL, XLenVT);
39  if (Inst.Opc == RISCV::LUI)
40  Result = CurDAG->getMachineNode(RISCV::LUI, DL, XLenVT, SDImm);
41  else
42  Result = CurDAG->getMachineNode(Inst.Opc, DL, XLenVT, SrcReg, SDImm);
43 
44  // Only the first instruction has X0 as its source.
45  SrcReg = SDValue(Result, 0);
46  }
47 
48  return Result;
49 }
50 
51 // Returns true if the Node is an ISD::AND with a constant argument. If so,
52 // set Mask to that constant value.
53 static bool isConstantMask(SDNode *Node, uint64_t &Mask) {
54  if (Node->getOpcode() == ISD::AND &&
55  Node->getOperand(1).getOpcode() == ISD::Constant) {
56  Mask = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
57  return true;
58  }
59  return false;
60 }
61 
63  // If we have a custom node, we have already selected.
64  if (Node->isMachineOpcode()) {
65  LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n");
66  Node->setNodeId(-1);
67  return;
68  }
69 
70  // Instruction Selection not handled by the auto-generated tablegen selection
71  // should be handled here.
72  unsigned Opcode = Node->getOpcode();
73  MVT XLenVT = Subtarget->getXLenVT();
74  SDLoc DL(Node);
75  EVT VT = Node->getValueType(0);
76 
77  switch (Opcode) {
78  case ISD::ADD: {
79  // Optimize (add r, imm) to (addi (addi r, imm0) imm1) if applicable. The
80  // immediate must be in specific ranges and have a single use.
81  if (auto *ConstOp = dyn_cast<ConstantSDNode>(Node->getOperand(1))) {
82  if (!(ConstOp->hasOneUse()))
83  break;
84  // The imm must be in range [-4096,-2049] or [2048,4094].
85  int64_t Imm = ConstOp->getSExtValue();
86  if (!(-4096 <= Imm && Imm <= -2049) && !(2048 <= Imm && Imm <= 4094))
87  break;
88  // Break the imm to imm0+imm1.
89  SDLoc DL(Node);
90  EVT VT = Node->getValueType(0);
91  const SDValue ImmOp0 = CurDAG->getTargetConstant(Imm - Imm / 2, DL, VT);
92  const SDValue ImmOp1 = CurDAG->getTargetConstant(Imm / 2, DL, VT);
93  auto *NodeAddi0 = CurDAG->getMachineNode(RISCV::ADDI, DL, VT,
94  Node->getOperand(0), ImmOp0);
95  auto *NodeAddi1 = CurDAG->getMachineNode(RISCV::ADDI, DL, VT,
96  SDValue(NodeAddi0, 0), ImmOp1);
97  ReplaceNode(Node, NodeAddi1);
98  return;
99  }
100  break;
101  }
102  case ISD::Constant: {
103  auto ConstNode = cast<ConstantSDNode>(Node);
104  if (VT == XLenVT && ConstNode->isNullValue()) {
106  RISCV::X0, XLenVT);
107  ReplaceNode(Node, New.getNode());
108  return;
109  }
110  int64_t Imm = ConstNode->getSExtValue();
111  if (XLenVT == MVT::i64) {
112  ReplaceNode(Node, selectImm(CurDAG, SDLoc(Node), Imm, XLenVT));
113  return;
114  }
115  break;
116  }
117  case ISD::FrameIndex: {
118  SDValue Imm = CurDAG->getTargetConstant(0, DL, XLenVT);
119  int FI = cast<FrameIndexSDNode>(Node)->getIndex();
120  SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
121  ReplaceNode(Node, CurDAG->getMachineNode(RISCV::ADDI, DL, VT, TFI, Imm));
122  return;
123  }
124  case ISD::SRL: {
125  if (!Subtarget->is64Bit())
126  break;
127  SDValue Op0 = Node->getOperand(0);
128  SDValue Op1 = Node->getOperand(1);
129  uint64_t Mask;
130  // Match (srl (and val, mask), imm) where the result would be a
131  // zero-extended 32-bit integer. i.e. the mask is 0xffffffff or the result
132  // is equivalent to this (SimplifyDemandedBits may have removed lower bits
133  // from the mask that aren't necessary due to the right-shifting).
134  if (Op1.getOpcode() == ISD::Constant &&
135  isConstantMask(Op0.getNode(), Mask)) {
136  uint64_t ShAmt = cast<ConstantSDNode>(Op1.getNode())->getZExtValue();
137 
138  if ((Mask | maskTrailingOnes<uint64_t>(ShAmt)) == 0xffffffff) {
139  SDValue ShAmtVal =
140  CurDAG->getTargetConstant(ShAmt, SDLoc(Node), XLenVT);
141  CurDAG->SelectNodeTo(Node, RISCV::SRLIW, XLenVT, Op0.getOperand(0),
142  ShAmtVal);
143  return;
144  }
145  }
146  break;
147  }
149  assert(!Subtarget->is64Bit() && "READ_CYCLE_WIDE is only used on riscv32");
150 
151  ReplaceNode(Node, CurDAG->getMachineNode(RISCV::ReadCycleWide, DL, MVT::i32,
153  Node->getOperand(0)));
154  return;
155  }
156 
157  // Select the default instruction.
158  SelectCode(Node);
159 }
160 
162  const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) {
163  switch (ConstraintID) {
165  // We just support simple memory operands that have a single address
166  // operand and need no special handling.
167  OutOps.push_back(Op);
168  return false;
170  OutOps.push_back(Op);
171  return false;
172  default:
173  break;
174  }
175 
176  return true;
177 }
178 
180  if (auto FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
181  Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT());
182  return true;
183  }
184  return false;
185 }
186 
187 // Check that it is a SLOI (Shift Left Ones Immediate). We first check that
188 // it is the right node tree:
189 //
190 // (OR (SHL RS1, VC2), VC1)
191 //
192 // and then we check that VC1, the mask used to fill with ones, is compatible
193 // with VC2, the shamt:
194 //
195 // VC1 == maskTrailingOnes<uint64_t>(VC2)
196 
198  MVT XLenVT = Subtarget->getXLenVT();
199  if (N.getOpcode() == ISD::OR) {
200  SDValue Or = N;
201  if (Or.getOperand(0).getOpcode() == ISD::SHL) {
202  SDValue Shl = Or.getOperand(0);
203  if (isa<ConstantSDNode>(Shl.getOperand(1)) &&
204  isa<ConstantSDNode>(Or.getOperand(1))) {
205  if (XLenVT == MVT::i64) {
206  uint64_t VC1 = Or.getConstantOperandVal(1);
207  uint64_t VC2 = Shl.getConstantOperandVal(1);
208  if (VC1 == maskTrailingOnes<uint64_t>(VC2)) {
209  RS1 = Shl.getOperand(0);
210  Shamt = CurDAG->getTargetConstant(VC2, SDLoc(N),
211  Shl.getOperand(1).getValueType());
212  return true;
213  }
214  }
215  if (XLenVT == MVT::i32) {
216  uint32_t VC1 = Or.getConstantOperandVal(1);
217  uint32_t VC2 = Shl.getConstantOperandVal(1);
218  if (VC1 == maskTrailingOnes<uint32_t>(VC2)) {
219  RS1 = Shl.getOperand(0);
220  Shamt = CurDAG->getTargetConstant(VC2, SDLoc(N),
221  Shl.getOperand(1).getValueType());
222  return true;
223  }
224  }
225  }
226  }
227  }
228  return false;
229 }
230 
231 // Check that it is a SROI (Shift Right Ones Immediate). We first check that
232 // it is the right node tree:
233 //
234 // (OR (SRL RS1, VC2), VC1)
235 //
236 // and then we check that VC1, the mask used to fill with ones, is compatible
237 // with VC2, the shamt:
238 //
239 // VC1 == maskLeadingOnes<uint64_t>(VC2)
240 
242  MVT XLenVT = Subtarget->getXLenVT();
243  if (N.getOpcode() == ISD::OR) {
244  SDValue Or = N;
245  if (Or.getOperand(0).getOpcode() == ISD::SRL) {
246  SDValue Srl = Or.getOperand(0);
247  if (isa<ConstantSDNode>(Srl.getOperand(1)) &&
248  isa<ConstantSDNode>(Or.getOperand(1))) {
249  if (XLenVT == MVT::i64) {
250  uint64_t VC1 = Or.getConstantOperandVal(1);
251  uint64_t VC2 = Srl.getConstantOperandVal(1);
252  if (VC1 == maskLeadingOnes<uint64_t>(VC2)) {
253  RS1 = Srl.getOperand(0);
254  Shamt = CurDAG->getTargetConstant(VC2, SDLoc(N),
255  Srl.getOperand(1).getValueType());
256  return true;
257  }
258  }
259  if (XLenVT == MVT::i32) {
260  uint32_t VC1 = Or.getConstantOperandVal(1);
261  uint32_t VC2 = Srl.getConstantOperandVal(1);
262  if (VC1 == maskLeadingOnes<uint32_t>(VC2)) {
263  RS1 = Srl.getOperand(0);
264  Shamt = CurDAG->getTargetConstant(VC2, SDLoc(N),
265  Srl.getOperand(1).getValueType());
266  return true;
267  }
268  }
269  }
270  }
271  }
272  return false;
273 }
274 
275 // Check that it is a RORI (Rotate Right Immediate). We first check that
276 // it is the right node tree:
277 //
278 // (ROTL RS1, VC)
279 //
280 // The compiler translates immediate rotations to the right given by the call
281 // to the rotateright32/rotateright64 intrinsics as rotations to the left.
282 // Since the rotation to the left can be easily emulated as a rotation to the
283 // right by negating the constant, there is no encoding for ROLI.
284 // We then select the immediate left rotations as RORI by the complementary
285 // constant:
286 //
287 // Shamt == XLen - VC
288 
290  MVT XLenVT = Subtarget->getXLenVT();
291  if (N.getOpcode() == ISD::ROTL) {
292  if (isa<ConstantSDNode>(N.getOperand(1))) {
293  if (XLenVT == MVT::i64) {
294  uint64_t VC = N.getConstantOperandVal(1);
295  Shamt = CurDAG->getTargetConstant((64 - VC), SDLoc(N),
296  N.getOperand(1).getValueType());
297  RS1 = N.getOperand(0);
298  return true;
299  }
300  if (XLenVT == MVT::i32) {
302  Shamt = CurDAG->getTargetConstant((32 - VC), SDLoc(N),
303  N.getOperand(1).getValueType());
304  RS1 = N.getOperand(0);
305  return true;
306  }
307  }
308  }
309  return false;
310 }
311 
312 
313 // Check that it is a SLLIUW (Shift Logical Left Immediate Unsigned i32
314 // on RV64).
315 // SLLIUW is the same as SLLI except for the fact that it clears the bits
316 // XLEN-1:32 of the input RS1 before shifting.
317 // We first check that it is the right node tree:
318 //
319 // (AND (SHL RS1, VC2), VC1)
320 //
321 // We check that VC2, the shamt is less than 32, otherwise the pattern is
322 // exactly the same as SLLI and we give priority to that.
323 // Eventually we check that that VC1, the mask used to clear the upper 32 bits
324 // of RS1, is correct:
325 //
326 // VC1 == (0xFFFFFFFF << VC2)
327 
329  if (N.getOpcode() == ISD::AND && Subtarget->getXLenVT() == MVT::i64) {
330  SDValue And = N;
331  if (And.getOperand(0).getOpcode() == ISD::SHL) {
332  SDValue Shl = And.getOperand(0);
333  if (isa<ConstantSDNode>(Shl.getOperand(1)) &&
334  isa<ConstantSDNode>(And.getOperand(1))) {
335  uint64_t VC1 = And.getConstantOperandVal(1);
336  uint64_t VC2 = Shl.getConstantOperandVal(1);
337  if (VC2 < 32 && VC1 == ((uint64_t)0xFFFFFFFF << VC2)) {
338  RS1 = Shl.getOperand(0);
339  Shamt = CurDAG->getTargetConstant(VC2, SDLoc(N),
340  Shl.getOperand(1).getValueType());
341  return true;
342  }
343  }
344  }
345  }
346  return false;
347 }
348 
349 // Check that it is a SLOIW (Shift Left Ones Immediate i32 on RV64).
350 // We first check that it is the right node tree:
351 //
352 // (SIGN_EXTEND_INREG (OR (SHL RS1, VC2), VC1))
353 //
354 // and then we check that VC1, the mask used to fill with ones, is compatible
355 // with VC2, the shamt:
356 //
357 // VC1 == maskTrailingOnes<uint32_t>(VC2)
358 
360  if (Subtarget->getXLenVT() == MVT::i64 &&
362  cast<VTSDNode>(N.getOperand(1))->getVT() == MVT::i32) {
363  if (N.getOperand(0).getOpcode() == ISD::OR) {
364  SDValue Or = N.getOperand(0);
365  if (Or.getOperand(0).getOpcode() == ISD::SHL) {
366  SDValue Shl = Or.getOperand(0);
367  if (isa<ConstantSDNode>(Shl.getOperand(1)) &&
368  isa<ConstantSDNode>(Or.getOperand(1))) {
369  uint32_t VC1 = Or.getConstantOperandVal(1);
370  uint32_t VC2 = Shl.getConstantOperandVal(1);
371  if (VC1 == maskTrailingOnes<uint32_t>(VC2)) {
372  RS1 = Shl.getOperand(0);
373  Shamt = CurDAG->getTargetConstant(VC2, SDLoc(N),
374  Shl.getOperand(1).getValueType());
375  return true;
376  }
377  }
378  }
379  }
380  }
381  return false;
382 }
383 
384 // Check that it is a SROIW (Shift Right Ones Immediate i32 on RV64).
385 // We first check that it is the right node tree:
386 //
387 // (OR (SHL RS1, VC2), VC1)
388 //
389 // and then we check that VC1, the mask used to fill with ones, is compatible
390 // with VC2, the shamt:
391 //
392 // VC1 == maskLeadingOnes<uint32_t>(VC2)
393 
395  if (N.getOpcode() == ISD::OR && Subtarget->getXLenVT() == MVT::i64) {
396  SDValue Or = N;
397  if (Or.getOperand(0).getOpcode() == ISD::SRL) {
398  SDValue Srl = Or.getOperand(0);
399  if (isa<ConstantSDNode>(Srl.getOperand(1)) &&
400  isa<ConstantSDNode>(Or.getOperand(1))) {
401  uint32_t VC1 = Or.getConstantOperandVal(1);
402  uint32_t VC2 = Srl.getConstantOperandVal(1);
403  if (VC1 == maskLeadingOnes<uint32_t>(VC2)) {
404  RS1 = Srl.getOperand(0);
405  Shamt = CurDAG->getTargetConstant(VC2, SDLoc(N),
406  Srl.getOperand(1).getValueType());
407  return true;
408  }
409  }
410  }
411  }
412  return false;
413 }
414 
415 // Check that it is a RORIW (i32 Right Rotate Immediate on RV64).
416 // We first check that it is the right node tree:
417 //
418 // (SIGN_EXTEND_INREG (OR (SHL (AsserSext RS1, i32), VC2),
419 // (SRL (AND (AssertSext RS2, i32), VC3), VC1)))
420 //
421 // Then we check that the constant operands respect these constraints:
422 //
423 // VC2 == 32 - VC1
424 // VC3 == maskLeadingOnes<uint32_t>(VC2)
425 //
426 // being VC1 the Shamt we need, VC2 the complementary of Shamt over 32
427 // and VC3 a 32 bit mask of (32 - VC1) leading ones.
428 
430  if (N.getOpcode() == ISD::SIGN_EXTEND_INREG &&
431  Subtarget->getXLenVT() == MVT::i64 &&
432  cast<VTSDNode>(N.getOperand(1))->getVT() == MVT::i32) {
433  if (N.getOperand(0).getOpcode() == ISD::OR) {
434  SDValue Or = N.getOperand(0);
435  if (Or.getOperand(0).getOpcode() == ISD::SHL &&
436  Or.getOperand(1).getOpcode() == ISD::SRL) {
437  SDValue Shl = Or.getOperand(0);
438  SDValue Srl = Or.getOperand(1);
439  if (Srl.getOperand(0).getOpcode() == ISD::AND) {
440  SDValue And = Srl.getOperand(0);
441  if (isa<ConstantSDNode>(Srl.getOperand(1)) &&
442  isa<ConstantSDNode>(Shl.getOperand(1)) &&
443  isa<ConstantSDNode>(And.getOperand(1))) {
444  uint32_t VC1 = Srl.getConstantOperandVal(1);
445  uint32_t VC2 = Shl.getConstantOperandVal(1);
446  uint32_t VC3 = And.getConstantOperandVal(1);
447  if (VC2 == (32 - VC1) &&
448  VC3 == maskLeadingOnes<uint32_t>(VC2)) {
449  RS1 = Shl.getOperand(0);
450  Shamt = CurDAG->getTargetConstant(VC1, SDLoc(N),
451  Srl.getOperand(1).getValueType());
452  return true;
453  }
454  }
455  }
456  }
457  }
458  }
459  return false;
460 }
461 
462 // Check that it is a FSRIW (i32 Funnel Shift Right Immediate on RV64).
463 // We first check that it is the right node tree:
464 //
465 // (SIGN_EXTEND_INREG (OR (SHL (AsserSext RS1, i32), VC2),
466 // (SRL (AND (AssertSext RS2, i32), VC3), VC1)))
467 //
468 // Then we check that the constant operands respect these constraints:
469 //
470 // VC2 == 32 - VC1
471 // VC3 == maskLeadingOnes<uint32_t>(VC2)
472 //
473 // being VC1 the Shamt we need, VC2 the complementary of Shamt over 32
474 // and VC3 a 32 bit mask of (32 - VC1) leading ones.
475 
477  SDValue &Shamt) {
478  if (N.getOpcode() == ISD::SIGN_EXTEND_INREG &&
479  Subtarget->getXLenVT() == MVT::i64 &&
480  cast<VTSDNode>(N.getOperand(1))->getVT() == MVT::i32) {
481  if (N.getOperand(0).getOpcode() == ISD::OR) {
482  SDValue Or = N.getOperand(0);
483  if (Or.getOperand(0).getOpcode() == ISD::SHL &&
484  Or.getOperand(1).getOpcode() == ISD::SRL) {
485  SDValue Shl = Or.getOperand(0);
486  SDValue Srl = Or.getOperand(1);
487  if (Srl.getOperand(0).getOpcode() == ISD::AND) {
488  SDValue And = Srl.getOperand(0);
489  if (isa<ConstantSDNode>(Srl.getOperand(1)) &&
490  isa<ConstantSDNode>(Shl.getOperand(1)) &&
491  isa<ConstantSDNode>(And.getOperand(1))) {
492  uint32_t VC1 = Srl.getConstantOperandVal(1);
493  uint32_t VC2 = Shl.getConstantOperandVal(1);
494  uint32_t VC3 = And.getConstantOperandVal(1);
495  if (VC2 == (32 - VC1) &&
496  VC3 == maskLeadingOnes<uint32_t>(VC2)) {
497  RS1 = Shl.getOperand(0);
498  RS2 = And.getOperand(0);
499  Shamt = CurDAG->getTargetConstant(VC1, SDLoc(N),
500  Srl.getOperand(1).getValueType());
501  return true;
502  }
503  }
504  }
505  }
506  }
507  }
508  return false;
509 }
510 
511 // Merge an ADDI into the offset of a load/store instruction where possible.
512 // (load (addi base, off1), off2) -> (load base, off1+off2)
513 // (store val, (addi base, off1), off2) -> (store val, base, off1+off2)
514 // This is possible when off1+off2 fits a 12-bit immediate.
515 void RISCVDAGToDAGISel::doPeepholeLoadStoreADDI() {
517  ++Position;
518 
519  while (Position != CurDAG->allnodes_begin()) {
520  SDNode *N = &*--Position;
521  // Skip dead nodes and any non-machine opcodes.
522  if (N->use_empty() || !N->isMachineOpcode())
523  continue;
524 
525  int OffsetOpIdx;
526  int BaseOpIdx;
527 
528  // Only attempt this optimisation for I-type loads and S-type stores.
529  switch (N->getMachineOpcode()) {
530  default:
531  continue;
532  case RISCV::LB:
533  case RISCV::LH:
534  case RISCV::LW:
535  case RISCV::LBU:
536  case RISCV::LHU:
537  case RISCV::LWU:
538  case RISCV::LD:
539  case RISCV::FLW:
540  case RISCV::FLD:
541  BaseOpIdx = 0;
542  OffsetOpIdx = 1;
543  break;
544  case RISCV::SB:
545  case RISCV::SH:
546  case RISCV::SW:
547  case RISCV::SD:
548  case RISCV::FSW:
549  case RISCV::FSD:
550  BaseOpIdx = 1;
551  OffsetOpIdx = 2;
552  break;
553  }
554 
555  if (!isa<ConstantSDNode>(N->getOperand(OffsetOpIdx)))
556  continue;
557 
558  SDValue Base = N->getOperand(BaseOpIdx);
559 
560  // If the base is an ADDI, we can merge it in to the load/store.
561  if (!Base.isMachineOpcode() || Base.getMachineOpcode() != RISCV::ADDI)
562  continue;
563 
564  SDValue ImmOperand = Base.getOperand(1);
565  uint64_t Offset2 = N->getConstantOperandVal(OffsetOpIdx);
566 
567  if (auto Const = dyn_cast<ConstantSDNode>(ImmOperand)) {
568  int64_t Offset1 = Const->getSExtValue();
569  int64_t CombinedOffset = Offset1 + Offset2;
570  if (!isInt<12>(CombinedOffset))
571  continue;
572  ImmOperand = CurDAG->getTargetConstant(CombinedOffset, SDLoc(ImmOperand),
573  ImmOperand.getValueType());
574  } else if (auto GA = dyn_cast<GlobalAddressSDNode>(ImmOperand)) {
575  // If the off1 in (addi base, off1) is a global variable's address (its
576  // low part, really), then we can rely on the alignment of that variable
577  // to provide a margin of safety before off1 can overflow the 12 bits.
578  // Check if off2 falls within that margin; if so off1+off2 can't overflow.
579  const DataLayout &DL = CurDAG->getDataLayout();
580  Align Alignment = GA->getGlobal()->getPointerAlignment(DL);
581  if (Offset2 != 0 && Alignment <= Offset2)
582  continue;
583  int64_t Offset1 = GA->getOffset();
584  int64_t CombinedOffset = Offset1 + Offset2;
585  ImmOperand = CurDAG->getTargetGlobalAddress(
586  GA->getGlobal(), SDLoc(ImmOperand), ImmOperand.getValueType(),
587  CombinedOffset, GA->getTargetFlags());
588  } else if (auto CP = dyn_cast<ConstantPoolSDNode>(ImmOperand)) {
589  // Ditto.
590  Align Alignment = CP->getAlign();
591  if (Offset2 != 0 && Alignment <= Offset2)
592  continue;
593  int64_t Offset1 = CP->getOffset();
594  int64_t CombinedOffset = Offset1 + Offset2;
595  ImmOperand = CurDAG->getTargetConstantPool(
596  CP->getConstVal(), ImmOperand.getValueType(), CP->getAlign(),
597  CombinedOffset, CP->getTargetFlags());
598  } else {
599  continue;
600  }
601 
602  LLVM_DEBUG(dbgs() << "Folding add-immediate into mem-op:\nBase: ");
603  LLVM_DEBUG(Base->dump(CurDAG));
604  LLVM_DEBUG(dbgs() << "\nN: ");
605  LLVM_DEBUG(N->dump(CurDAG));
606  LLVM_DEBUG(dbgs() << "\n");
607 
608  // Modify the offset operand of the load/store.
609  if (BaseOpIdx == 0) // Load
610  CurDAG->UpdateNodeOperands(N, Base.getOperand(0), ImmOperand,
611  N->getOperand(2));
612  else // Store
613  CurDAG->UpdateNodeOperands(N, N->getOperand(0), Base.getOperand(0),
614  ImmOperand, N->getOperand(3));
615 
616  // The add-immediate may now be dead, in which case remove it.
617  if (Base.getNode()->use_empty())
618  CurDAG->RemoveDeadNode(Base.getNode());
619  }
620 }
621 
622 // This pass converts a legalized DAG into a RISCV-specific DAG, ready
623 // for instruction scheduling.
625  return new RISCVDAGToDAGISel(TM);
626 }
static bool isConstantMask(SDNode *Node, uint64_t &Mask)
SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type...
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:111
bool SelectRORIW(SDValue N, SDValue &RS1, SDValue &Shamt)
EVT getValueType() const
Return the ValueType of the referenced return value.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=None, int Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:680
void setNodeId(int Id)
Set unique node id.
SDNode * getNode() const
get the SDNode which holds the desired result
bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, std::vector< SDValue > &OutOps) override
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode...
void Select(SDNode *Node) override
Main hook for targets to transform nodes into machine nodes.
Shift and rotation operations.
Definition: ISDOpcodes.h:576
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s), MachineInstr opcode, and operands.
uint64_t getConstantOperandVal(unsigned i) const
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:497
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:424
std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:80
Position
Position to insert a new instruction relative to an existing instruction.
FunctionPass * createRISCVISelDag(RISCVTargetMachine &TM)
bool SelectFSRIW(SDValue N, SDValue &RS1, SDValue &RS2, SDValue &Shamt)
SDValue getTargetFrameIndex(int FI, EVT VT)
Definition: SelectionDAG.h:669
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:223
bool SelectSROI(SDValue N, SDValue &RS1, SDValue &Shamt)
bool SelectSLLIUW(SDValue N, SDValue &RS1, SDValue &Shamt)
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:618
Machine Value Type.
This instruction implements an extending load to FP stack slots.
bool isMachineOpcode() const
const SDValue & getOperand(unsigned Num) const
bool SelectAddrFI(SDValue Addr, SDValue &Base)
bool SelectSROIW(SDValue N, SDValue &RS1, SDValue &Shamt)
unsigned getMachineOpcode() const
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
Extended Value Type.
Definition: ValueTypes.h:35
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
bool use_empty() const
Return true if there are no uses of this node.
void dump() const
Dump this node, for debugging.
Iterator for intrusive lists based on ilist_node.
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:664
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:223
static SDNode * selectImm(SelectionDAG *CurDAG, const SDLoc &DL, int64_t Imm, MVT XLenVT)
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:883
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
allnodes_const_iterator allnodes_begin() const
Definition: SelectionDAG.h:474
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
bool SelectSLOIW(SDValue N, SDValue &RS1, SDValue &Shamt)
RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine)
bool SelectRORI(SDValue N, SDValue &RS1, SDValue &Shamt)
void PostprocessISelDAG() override
PostprocessISelDAG() - This hook allows the target to hack on the graph right after selection...
bool SelectSLOI(SDValue N, SDValue &RS1, SDValue &Shamt)
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:551
void generateInstSeq(int64_t Val, bool IsRV64, InstSeq &Res)
Definition: RISCVMatInt.cpp:19
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:744
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:665
#define N
unsigned getOpcode() const
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
Definition: SelectionDAG.h:494
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
SDValue getRegister(unsigned Reg, EVT VT)
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
void ReplaceNode(SDNode *F, SDNode *T)
Replace all uses of F with T, then remove F from the DAG.
const SDValue & getOperand(unsigned i) const
#define LLVM_DEBUG(X)
Definition: Debug.h:122
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL