LLVM  4.0.0
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,
320  CurDAG->getTargetConstant(0, SDLoc(N), MVT::i16));
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);
346  SDValue Offset = CurDAG->getTargetConstant(CST, DL, MVT::i16);
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.
353  MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
354  MemOp[0] = ST->getMemOperand();
355  cast<MachineSDNode>(ResNode)->setMemRefs(MemOp, MemOp + 1);
356 
357  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
358  CurDAG->RemoveDeadNode(N);
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.
410  MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
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));
416  CurDAG->RemoveDeadNode(N);
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));
456  CurDAG->RemoveDeadNode(N);
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));
471  CurDAG->RemoveDeadNode(N);
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 
560  CodeGenOpt::Level OptLevel) {
561  return new AVRDAGToDAGISel(TM, OptLevel);
562 }
563 
564 } // end of namespace llvm
565 
SDValue getValue(unsigned R) 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:1309
bool selectIndexedLoad(SDNode *N)
size_t i
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...
unsigned getReg() const
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition: ISDOpcodes.h:131
const SDValue & getOperand(unsigned Num) const
bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode, std::vector< SDValue > &OutOps) override
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode...
const SDValue & getBasePtr() const
MachineFunction * MF
A description of a memory reference used in the backend.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Represents an abstract call instruction, which includes a bunch of information.
bool isProgramMemoryAccess(MemSDNode const *N)
Definition: AVR.h:48
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
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 TargetLowering * getTargetLowering() const
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
const AVRTargetLowering * getTargetLowering() const override
Definition: AVRSubtarget.h:45
Reg
All possible values of the reg field in the ModR/M byte.
SimpleValueType SimpleTy
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:535
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:200
const SDValue & getBasePtr() const
const APInt & getAPIntValue() const
EVT getMemoryVT() const
Return the type of the in-memory value.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:487
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:328
This class is used to represent ISD::STORE nodes.
SDNode * getNode() const
get the SDNode which holds the desired result
CodeGenOpt::Level OptLevel
MVT - Machine Value Type.
const SDValue & getOperand(unsigned i) const
bool SelectAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Disp)
uint32_t Offset
unsigned getOpcode() const
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
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).
const SDValue & getValue() const
EVT - Extended Value Type.
Definition: ValueTypes.h:31
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc, or post-dec.
AVRDAGToDAGISel(AVRTargetMachine &TM, CodeGenOpt::Level OptLevel)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const SDValue & getOffset() const
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
const SDValue & getChain() const
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
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:584
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
A specific AVR target MCU.
Definition: AVRSubtarget.h:33
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
bool hasAnyUseOfValue(unsigned Value) const
Return true if there are any use of the indicated value.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:610
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:536
#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:287
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition: ISDOpcodes.h:175
EVT getValueType() const
Return the ValueType of the referenced return value.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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...
unsigned selectIndexedProgMemLoad(const LoadSDNode *LD, MVT VT)
#define DEBUG(X)
Definition: Debug.h:100
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
int * Ptr
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:381
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
MVT getSimpleVT() const
getSimpleVT - Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:226
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
Definition: ISDOpcodes.h:799
BRIND - Indirect branch.
Definition: ISDOpcodes.h:556
This class is used to represent ISD::LOAD nodes.