LLVM  6.0.0svn
AVRISelDAGToDAG.cpp
Go to the documentation of this file.
1 //===-- AVRISelDAGToDAG.cpp - A dag to dag inst selector for AVR ----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines an instruction selector for the AVR target.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "AVR.h"
15 #include "AVRTargetMachine.h"
17 
20 #include "llvm/Support/Debug.h"
22 
23 #define DEBUG_TYPE "avr-isel"
24 
25 namespace llvm {
26 
27 /// Lowers LLVM IR (in DAG form) to AVR MC instructions (in DAG form).
29 public:
31  : SelectionDAGISel(TM, OptLevel), Subtarget(nullptr) {}
32 
33  StringRef getPassName() const override {
34  return "AVR DAG->DAG Instruction Selection";
35  }
36 
37  bool runOnMachineFunction(MachineFunction &MF) override;
38 
39  bool SelectAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Disp);
40 
41  bool selectIndexedLoad(SDNode *N);
42  unsigned selectIndexedProgMemLoad(const LoadSDNode *LD, MVT VT);
43 
44  bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode,
45  std::vector<SDValue> &OutOps) override;
46 
47 // Include the pieces autogenerated from the target description.
48 #include "AVRGenDAGISel.inc"
49 
50 private:
51  void Select(SDNode *N) override;
52  bool trySelect(SDNode *N);
53 
54  template <unsigned NodeType> bool select(SDNode *N);
55  bool selectMultiplication(SDNode *N);
56 
57  const AVRSubtarget *Subtarget;
58 };
59 
61  Subtarget = &MF.getSubtarget<AVRSubtarget>();
63 }
64 
66  SDValue &Disp) {
67  SDLoc dl(Op);
68  auto DL = CurDAG->getDataLayout();
69  MVT PtrVT = getTargetLowering()->getPointerTy(DL);
70 
71  // if the address is a frame index get the TargetFrameIndex.
72  if (const FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) {
73  Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), PtrVT);
74  Disp = CurDAG->getTargetConstant(0, dl, MVT::i8);
75 
76  return true;
77  }
78 
79  // Match simple Reg + uimm6 operands.
80  if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB &&
82  return false;
83  }
84 
85  if (const ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
86  int RHSC = (int)RHS->getZExtValue();
87 
88  // Convert negative offsets into positives ones.
89  if (N.getOpcode() == ISD::SUB) {
90  RHSC = -RHSC;
91  }
92 
93  // <#Frame index + const>
94  // Allow folding offsets bigger than 63 so the frame pointer can be used
95  // directly instead of copying it around by adjusting and restoring it for
96  // each access.
97  if (N.getOperand(0).getOpcode() == ISD::FrameIndex) {
98  int FI = cast<FrameIndexSDNode>(N.getOperand(0))->getIndex();
99 
100  Base = CurDAG->getTargetFrameIndex(FI, PtrVT);
101  Disp = CurDAG->getTargetConstant(RHSC, dl, MVT::i16);
102 
103  return true;
104  }
105 
106  // The value type of the memory instruction determines what is the maximum
107  // offset allowed.
108  MVT VT = cast<MemSDNode>(Op)->getMemoryVT().getSimpleVT();
109 
110  // We only accept offsets that fit in 6 bits (unsigned).
111  if (isUInt<6>(RHSC) && (VT == MVT::i8 || VT == MVT::i16)) {
112  Base = N.getOperand(0);
113  Disp = CurDAG->getTargetConstant(RHSC, dl, MVT::i8);
114 
115  return true;
116  }
117  }
118 
119  return false;
120 }
121 
123  const LoadSDNode *LD = cast<LoadSDNode>(N);
125  MVT VT = LD->getMemoryVT().getSimpleVT();
127 
128  // We only care if this load uses a POSTINC or PREDEC mode.
129  if ((LD->getExtensionType() != ISD::NON_EXTLOAD) ||
130  (AM != ISD::POST_INC && AM != ISD::PRE_DEC)) {
131 
132  return false;
133  }
134 
135  unsigned Opcode = 0;
136  bool isPre = (AM == ISD::PRE_DEC);
137  int Offs = cast<ConstantSDNode>(LD->getOffset())->getSExtValue();
138 
139  switch (VT.SimpleTy) {
140  case MVT::i8: {
141  if ((!isPre && Offs != 1) || (isPre && Offs != -1)) {
142  return false;
143  }
144 
145  Opcode = (isPre) ? AVR::LDRdPtrPd : AVR::LDRdPtrPi;
146  break;
147  }
148  case MVT::i16: {
149  if ((!isPre && Offs != 2) || (isPre && Offs != -2)) {
150  return false;
151  }
152 
153  Opcode = (isPre) ? AVR::LDWRdPtrPd : AVR::LDWRdPtrPi;
154  break;
155  }
156  default:
157  return false;
158  }
159 
160  SDNode *ResNode = CurDAG->getMachineNode(Opcode, SDLoc(N), VT,
161  PtrVT, MVT::Other,
162  LD->getBasePtr(), LD->getChain());
163  ReplaceUses(N, ResNode);
165 
166  return true;
167 }
168 
170  MVT VT) {
172 
173  // Progmem indexed loads only work in POSTINC mode.
174  if (LD->getExtensionType() != ISD::NON_EXTLOAD || AM != ISD::POST_INC) {
175  return 0;
176  }
177 
178  unsigned Opcode = 0;
179  int Offs = cast<ConstantSDNode>(LD->getOffset())->getSExtValue();
180 
181  switch (VT.SimpleTy) {
182  case MVT::i8: {
183  if (Offs != 1) {
184  return 0;
185  }
186  Opcode = AVR::LPMRdZPi;
187  break;
188  }
189  case MVT::i16: {
190  if (Offs != 2) {
191  return 0;
192  }
193  Opcode = AVR::LPMWRdZPi;
194  break;
195  }
196  default:
197  return 0;
198  }
199 
200  return Opcode;
201 }
202 
204  unsigned ConstraintCode,
205  std::vector<SDValue> &OutOps) {
206  assert((ConstraintCode == InlineAsm::Constraint_m ||
207  ConstraintCode == InlineAsm::Constraint_Q) &&
208  "Unexpected asm memory constraint");
209 
211  const AVRSubtarget &STI = MF->getSubtarget<AVRSubtarget>();
212  const TargetLowering &TL = *STI.getTargetLowering();
213  SDLoc dl(Op);
214  auto DL = CurDAG->getDataLayout();
215 
216  const RegisterSDNode *RegNode = dyn_cast<RegisterSDNode>(Op);
217 
218  // If address operand is of PTRDISPREGS class, all is OK, then.
219  if (RegNode &&
220  RI.getRegClass(RegNode->getReg()) == &AVR::PTRDISPREGSRegClass) {
221  OutOps.push_back(Op);
222  return false;
223  }
224 
225  if (Op->getOpcode() == ISD::FrameIndex) {
226  SDValue Base, Disp;
227 
228  if (SelectAddr(Op.getNode(), Op, Base, Disp)) {
229  OutOps.push_back(Base);
230  OutOps.push_back(Disp);
231 
232  return false;
233  }
234 
235  return true;
236  }
237 
238  // If Op is add 'register, immediate' and
239  // register is either virtual register or register of PTRDISPREGSRegClass
240  if (Op->getOpcode() == ISD::ADD || Op->getOpcode() == ISD::SUB) {
241  SDValue CopyFromRegOp = Op->getOperand(0);
242  SDValue ImmOp = Op->getOperand(1);
243  ConstantSDNode *ImmNode = dyn_cast<ConstantSDNode>(ImmOp);
244 
245  unsigned Reg;
246  bool CanHandleRegImmOpt = true;
247 
248  CanHandleRegImmOpt &= ImmNode != 0;
249  CanHandleRegImmOpt &= ImmNode->getAPIntValue().getZExtValue() < 64;
250 
251  if (CopyFromRegOp->getOpcode() == ISD::CopyFromReg) {
252  RegisterSDNode *RegNode =
253  cast<RegisterSDNode>(CopyFromRegOp->getOperand(1));
254  Reg = RegNode->getReg();
255  CanHandleRegImmOpt &= (TargetRegisterInfo::isVirtualRegister(Reg) ||
256  AVR::PTRDISPREGSRegClass.contains(Reg));
257  } else {
258  CanHandleRegImmOpt = false;
259  }
260 
261  // If we detect proper case - correct virtual register class
262  // if needed and go to another inlineasm operand.
263  if (CanHandleRegImmOpt) {
264  SDValue Base, Disp;
265 
266  if (RI.getRegClass(Reg) != &AVR::PTRDISPREGSRegClass) {
267  SDLoc dl(CopyFromRegOp);
268 
269  unsigned VReg = RI.createVirtualRegister(&AVR::PTRDISPREGSRegClass);
270 
272  CurDAG->getCopyToReg(CopyFromRegOp, dl, VReg, CopyFromRegOp);
273 
274  SDValue NewCopyFromRegOp =
275  CurDAG->getCopyFromReg(CopyToReg, dl, VReg, TL.getPointerTy(DL));
276 
277  Base = NewCopyFromRegOp;
278  } else {
279  Base = CopyFromRegOp;
280  }
281 
282  if (ImmNode->getValueType(0) != MVT::i8) {
283  Disp = CurDAG->getTargetConstant(ImmNode->getAPIntValue().getZExtValue(), dl, MVT::i8);
284  } else {
285  Disp = ImmOp;
286  }
287 
288  OutOps.push_back(Base);
289  OutOps.push_back(Disp);
290 
291  return false;
292  }
293  }
294 
295  // More generic case.
296  // Create chain that puts Op into pointer register
297  // and return that register.
298  unsigned VReg = RI.createVirtualRegister(&AVR::PTRDISPREGSRegClass);
299 
300  SDValue CopyToReg = CurDAG->getCopyToReg(Op, dl, VReg, Op);
302  CurDAG->getCopyFromReg(CopyToReg, dl, VReg, TL.getPointerTy(DL));
303 
304  OutOps.push_back(CopyFromReg);
305 
306  return false;
307 }
308 
309 template <> bool AVRDAGToDAGISel::select<ISD::FrameIndex>(SDNode *N) {
310  auto DL = CurDAG->getDataLayout();
311 
312  // Convert the frameindex into a temp instruction that will hold the
313  // effective address of the final stack slot.
314  int FI = cast<FrameIndexSDNode>(N)->getIndex();
315  SDValue TFI =
316  CurDAG->getTargetFrameIndex(FI, getTargetLowering()->getPointerTy(DL));
317 
318  CurDAG->SelectNodeTo(N, AVR::FRMIDX,
319  getTargetLowering()->getPointerTy(DL), TFI,
321  return true;
322 }
323 
324 template <> bool AVRDAGToDAGISel::select<ISD::STORE>(SDNode *N) {
325  // Use the STD{W}SPQRr pseudo instruction when passing arguments through
326  // the stack on function calls for further expansion during the PEI phase.
327  const StoreSDNode *ST = cast<StoreSDNode>(N);
328  SDValue BasePtr = ST->getBasePtr();
329 
330  // Early exit when the base pointer is a frame index node or a constant.
331  if (isa<FrameIndexSDNode>(BasePtr) || isa<ConstantSDNode>(BasePtr) ||
332  BasePtr.isUndef()) {
333  return false;
334  }
335 
336  const RegisterSDNode *RN = dyn_cast<RegisterSDNode>(BasePtr.getOperand(0));
337  // Only stores where SP is the base pointer are valid.
338  if (!RN || (RN->getReg() != AVR::SP)) {
339  return false;
340  }
341 
342  int CST = (int)cast<ConstantSDNode>(BasePtr.getOperand(1))->getZExtValue();
343  SDValue Chain = ST->getChain();
344  EVT VT = ST->getValue().getValueType();
345  SDLoc DL(N);
347  SDValue Ops[] = {BasePtr.getOperand(0), Offset, ST->getValue(), Chain};
348  unsigned Opc = (VT == MVT::i16) ? AVR::STDWSPQRr : AVR::STDSPQRr;
349 
350  SDNode *ResNode = CurDAG->getMachineNode(Opc, DL, MVT::Other, Ops);
351 
352  // Transfer memory operands.
354  MemOp[0] = ST->getMemOperand();
355  cast<MachineSDNode>(ResNode)->setMemRefs(MemOp, MemOp + 1);
356 
357  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
359 
360  return true;
361 }
362 
363 template <> bool AVRDAGToDAGISel::select<ISD::LOAD>(SDNode *N) {
364  const LoadSDNode *LD = cast<LoadSDNode>(N);
365  if (!AVR::isProgramMemoryAccess(LD)) {
366  // Check if the opcode can be converted into an indexed load.
367  return selectIndexedLoad(N);
368  }
369 
370  assert(Subtarget->hasLPM() && "cannot load from program memory on this mcu");
371 
372  // This is a flash memory load, move the pointer into R31R30 and emit
373  // the lpm instruction.
374  MVT VT = LD->getMemoryVT().getSimpleVT();
375  SDValue Chain = LD->getChain();
376  SDValue Ptr = LD->getBasePtr();
377  SDNode *ResNode;
378  SDLoc DL(N);
379 
380  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, Ptr, SDValue());
381  Ptr = CurDAG->getCopyFromReg(Chain, DL, AVR::R31R30, MVT::i16,
382  Chain.getValue(1));
383 
384  SDValue RegZ = CurDAG->getRegister(AVR::R31R30, MVT::i16);
385 
386  // Check if the opcode can be converted into an indexed load.
387  if (unsigned LPMOpc = selectIndexedProgMemLoad(LD, VT)) {
388  // It is legal to fold the load into an indexed load.
389  ResNode = CurDAG->getMachineNode(LPMOpc, DL, VT, MVT::i16, MVT::Other, Ptr,
390  RegZ);
391  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
392  } else {
393  // Selecting an indexed load is not legal, fallback to a normal load.
394  switch (VT.SimpleTy) {
395  case MVT::i8:
396  ResNode = CurDAG->getMachineNode(AVR::LPMRdZ, DL, MVT::i8, MVT::Other,
397  Ptr, RegZ);
398  break;
399  case MVT::i16:
400  ResNode = CurDAG->getMachineNode(AVR::LPMWRdZ, DL, MVT::i16,
401  MVT::Other, Ptr, RegZ);
402  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
403  break;
404  default:
405  llvm_unreachable("Unsupported VT!");
406  }
407  }
408 
409  // Transfer memory operands.
411  MemOp[0] = LD->getMemOperand();
412  cast<MachineSDNode>(ResNode)->setMemRefs(MemOp, MemOp + 1);
413 
414  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
415  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
417 
418  return true;
419 }
420 
421 template <> bool AVRDAGToDAGISel::select<AVRISD::CALL>(SDNode *N) {
422  SDValue InFlag;
423  SDValue Chain = N->getOperand(0);
424  SDValue Callee = N->getOperand(1);
425  unsigned LastOpNum = N->getNumOperands() - 1;
426 
427  // Direct calls are autogenerated.
428  unsigned Op = Callee.getOpcode();
430  return false;
431  }
432 
433  // Skip the incoming flag if present
434  if (N->getOperand(LastOpNum).getValueType() == MVT::Glue) {
435  --LastOpNum;
436  }
437 
438  SDLoc DL(N);
439  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, Callee, InFlag);
441  Ops.push_back(CurDAG->getRegister(AVR::R31R30, MVT::i16));
442 
443  // Map all operands into the new node.
444  for (unsigned i = 2, e = LastOpNum + 1; i != e; ++i) {
445  Ops.push_back(N->getOperand(i));
446  }
447 
448  Ops.push_back(Chain);
449  Ops.push_back(Chain.getValue(1));
450 
451  SDNode *ResNode =
452  CurDAG->getMachineNode(AVR::ICALL, DL, MVT::Other, MVT::Glue, Ops);
453 
454  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
455  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
457 
458  return true;
459 }
460 
461 template <> bool AVRDAGToDAGISel::select<ISD::BRIND>(SDNode *N) {
462  SDValue Chain = N->getOperand(0);
463  SDValue JmpAddr = N->getOperand(1);
464 
465  SDLoc DL(N);
466  // Move the destination address of the indirect branch into R31R30.
467  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, JmpAddr);
468  SDNode *ResNode = CurDAG->getMachineNode(AVR::IJMP, DL, MVT::Other, Chain);
469 
470  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
472 
473  return true;
474 }
475 
476 bool AVRDAGToDAGISel::selectMultiplication(llvm::SDNode *N) {
477  SDLoc DL(N);
478  MVT Type = N->getSimpleValueType(0);
479 
480  assert(Type == MVT::i8 && "unexpected value type");
481 
482  bool isSigned = N->getOpcode() == ISD::SMUL_LOHI;
483  unsigned MachineOp = isSigned ? AVR::MULSRdRr : AVR::MULRdRr;
484 
485  SDValue Lhs = N->getOperand(0);
486  SDValue Rhs = N->getOperand(1);
487  SDNode *Mul = CurDAG->getMachineNode(MachineOp, DL, MVT::Glue, Lhs, Rhs);
488  SDValue InChain = CurDAG->getEntryNode();
489  SDValue InGlue = SDValue(Mul, 0);
490 
491  // Copy the low half of the result, if it is needed.
492  if (N->hasAnyUseOfValue(0)) {
493  SDValue CopyFromLo =
494  CurDAG->getCopyFromReg(InChain, DL, AVR::R0, Type, InGlue);
495 
496  ReplaceUses(SDValue(N, 0), CopyFromLo);
497 
498  InChain = CopyFromLo.getValue(1);
499  InGlue = CopyFromLo.getValue(2);
500  }
501 
502  // Copy the high half of the result, if it is needed.
503  if (N->hasAnyUseOfValue(1)) {
504  SDValue CopyFromHi =
505  CurDAG->getCopyFromReg(InChain, DL, AVR::R1, Type, InGlue);
506 
507  ReplaceUses(SDValue(N, 1), CopyFromHi);
508 
509  InChain = CopyFromHi.getValue(1);
510  InGlue = CopyFromHi.getValue(2);
511  }
512 
514 
515  // We need to clear R1. This is currently done (dirtily)
516  // using a custom inserter.
517 
518  return true;
519 }
520 
521 void AVRDAGToDAGISel::Select(SDNode *N) {
522  // Dump information about the Node being selected
523  DEBUG(errs() << "Selecting: "; N->dump(CurDAG); errs() << "\n");
524 
525  // If we have a custom node, we already have selected!
526  if (N->isMachineOpcode()) {
527  DEBUG(errs() << "== "; N->dump(CurDAG); errs() << "\n");
528  N->setNodeId(-1);
529  return;
530  }
531 
532  // See if subclasses can handle this node.
533  if (trySelect(N))
534  return;
535 
536  // Select the default instruction
537  SelectCode(N);
538 }
539 
540 bool AVRDAGToDAGISel::trySelect(SDNode *N) {
541  unsigned Opcode = N->getOpcode();
542  SDLoc DL(N);
543 
544  switch (Opcode) {
545  // Nodes we fully handle.
546  case ISD::FrameIndex: return select<ISD::FrameIndex>(N);
547  case ISD::BRIND: return select<ISD::BRIND>(N);
548  case ISD::UMUL_LOHI:
549  case ISD::SMUL_LOHI: return selectMultiplication(N);
550 
551  // Nodes we handle partially. Other cases are autogenerated
552  case ISD::STORE: return select<ISD::STORE>(N);
553  case ISD::LOAD: return select<ISD::LOAD>(N);
554  case AVRISD::CALL: return select<AVRISD::CALL>(N);
555  default: return false;
556  }
557 }
558 
561  return new AVRDAGToDAGISel(TM, OptLevel);
562 }
563 
564 } // end of namespace llvm
565 
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOffset() const
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1542
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
bool selectIndexedLoad(SDNode *N)
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
void ReplaceUses(SDValue F, SDValue T)
ReplaceUses - replace all uses of the old node F with the use of the new node T.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
const SDValue & getBasePtr() const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
const SDValue & getValue() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:253
const SDValue & getChain() const
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc, or post-dec.
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition: ISDOpcodes.h:131
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode, std::vector< SDValue > &OutOps) override
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode...
void setNodeId(int Id)
Set unique node id.
SDNode * getNode() const
get the SDNode which holds the desired result
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
MachineFunction * MF
A description of a memory reference used in the backend.
Represents an abstract call instruction, which includes a bunch of information.
bool isProgramMemoryAccess(MemSDNode const *N)
Definition: AVR.h:46
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.
CopyToReg - This node has three operands: a chain, a register number to set to this value...
Definition: ISDOpcodes.h:170
const AVRTargetLowering * getTargetLowering() const override
Definition: AVRSubtarget.h:44
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
Reg
All possible values of the reg field in the ModR/M byte.
SimpleValueType SimpleTy
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:446
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:388
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
A generic AVR implementation.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
SDValue getTargetFrameIndex(int FI, EVT VT)
Definition: SelectionDAG.h:606
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:200
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:558
amdgpu Simplify well known AMD library false Value * Callee
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
CodeGenOpt::Level OptLevel
MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
Machine Value Type.
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
bool hasAnyUseOfValue(unsigned Value) const
Return true if there are any use of the indicated value.
const SDValue & getOperand(unsigned Num) const
bool SelectAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Disp)
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side...
const APInt & getAPIntValue() const
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
StringRef getPassName() const override
getPassName - Return a nice clean name for a pass.
void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
FunctionPass * createAVRISelDag(AVRTargetMachine &TM, CodeGenOpt::Level OptLevel)
Lowers LLVM IR (in DAG form) to AVR MC instructions (in DAG form).
Extended Value Type.
Definition: ValueTypes.h:34
AVRDAGToDAGISel(AVRTargetMachine &TM, CodeGenOpt::Level OptLevel)
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void dump() const
Dump this node, for debugging.
SDNode * SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type...
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:864
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:657
bool hasLPM() const
Definition: AVRSubtarget.h:61
EVT getMemoryVT() const
Return the type of the in-memory value.
A specific AVR target MCU.
Definition: AVRSubtarget.h:32
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:683
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:205
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:581
#define N
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
unsigned getOpcode() const
SDValue getValue(unsigned R) const
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition: ISDOpcodes.h:175
const TargetLowering * getTargetLowering() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getReg() const
SDValue getRegister(unsigned Reg, EVT VT)
unsigned selectIndexedProgMemLoad(const LoadSDNode *LD, MVT VT)
#define DEBUG(X)
Definition: Debug.h:118
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
const SDValue & getOperand(unsigned i) const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
MachineInstr::mmo_iterator allocateMemRefsArray(unsigned long Num)
allocateMemRefsArray - Allocate an array to hold MachineMemOperand pointers.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
Definition: ISDOpcodes.h:871
BRIND - Indirect branch.
Definition: ISDOpcodes.h:601
This class is used to represent ISD::LOAD nodes.