LLVM  8.0.1
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.
353  CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {ST->getMemOperand()});
354 
355  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
357 
358  return true;
359 }
360 
361 template <> bool AVRDAGToDAGISel::select<ISD::LOAD>(SDNode *N) {
362  const LoadSDNode *LD = cast<LoadSDNode>(N);
363  if (!AVR::isProgramMemoryAccess(LD)) {
364  // Check if the opcode can be converted into an indexed load.
365  return selectIndexedLoad(N);
366  }
367 
368  assert(Subtarget->hasLPM() && "cannot load from program memory on this mcu");
369 
370  // This is a flash memory load, move the pointer into R31R30 and emit
371  // the lpm instruction.
372  MVT VT = LD->getMemoryVT().getSimpleVT();
373  SDValue Chain = LD->getChain();
374  SDValue Ptr = LD->getBasePtr();
375  SDNode *ResNode;
376  SDLoc DL(N);
377 
378  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, Ptr, SDValue());
379  Ptr = CurDAG->getCopyFromReg(Chain, DL, AVR::R31R30, MVT::i16,
380  Chain.getValue(1));
381 
382  SDValue RegZ = CurDAG->getRegister(AVR::R31R30, MVT::i16);
383 
384  // Check if the opcode can be converted into an indexed load.
385  if (unsigned LPMOpc = selectIndexedProgMemLoad(LD, VT)) {
386  // It is legal to fold the load into an indexed load.
387  ResNode = CurDAG->getMachineNode(LPMOpc, DL, VT, MVT::i16, MVT::Other, Ptr,
388  RegZ);
389  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
390  } else {
391  // Selecting an indexed load is not legal, fallback to a normal load.
392  switch (VT.SimpleTy) {
393  case MVT::i8:
394  ResNode = CurDAG->getMachineNode(AVR::LPMRdZ, DL, MVT::i8, MVT::Other,
395  Ptr, RegZ);
396  break;
397  case MVT::i16:
398  ResNode = CurDAG->getMachineNode(AVR::LPMWRdZ, DL, MVT::i16,
399  MVT::Other, Ptr, RegZ);
400  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
401  break;
402  default:
403  llvm_unreachable("Unsupported VT!");
404  }
405  }
406 
407  // Transfer memory operands.
408  CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {LD->getMemOperand()});
409 
410  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
411  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
413 
414  return true;
415 }
416 
417 template <> bool AVRDAGToDAGISel::select<AVRISD::CALL>(SDNode *N) {
418  SDValue InFlag;
419  SDValue Chain = N->getOperand(0);
420  SDValue Callee = N->getOperand(1);
421  unsigned LastOpNum = N->getNumOperands() - 1;
422 
423  // Direct calls are autogenerated.
424  unsigned Op = Callee.getOpcode();
426  return false;
427  }
428 
429  // Skip the incoming flag if present
430  if (N->getOperand(LastOpNum).getValueType() == MVT::Glue) {
431  --LastOpNum;
432  }
433 
434  SDLoc DL(N);
435  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, Callee, InFlag);
437  Ops.push_back(CurDAG->getRegister(AVR::R31R30, MVT::i16));
438 
439  // Map all operands into the new node.
440  for (unsigned i = 2, e = LastOpNum + 1; i != e; ++i) {
441  Ops.push_back(N->getOperand(i));
442  }
443 
444  Ops.push_back(Chain);
445  Ops.push_back(Chain.getValue(1));
446 
447  SDNode *ResNode =
448  CurDAG->getMachineNode(AVR::ICALL, DL, MVT::Other, MVT::Glue, Ops);
449 
450  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
451  ReplaceUses(SDValue(N, 1), SDValue(ResNode, 1));
453 
454  return true;
455 }
456 
457 template <> bool AVRDAGToDAGISel::select<ISD::BRIND>(SDNode *N) {
458  SDValue Chain = N->getOperand(0);
459  SDValue JmpAddr = N->getOperand(1);
460 
461  SDLoc DL(N);
462  // Move the destination address of the indirect branch into R31R30.
463  Chain = CurDAG->getCopyToReg(Chain, DL, AVR::R31R30, JmpAddr);
464  SDNode *ResNode = CurDAG->getMachineNode(AVR::IJMP, DL, MVT::Other, Chain);
465 
466  ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
468 
469  return true;
470 }
471 
472 bool AVRDAGToDAGISel::selectMultiplication(llvm::SDNode *N) {
473  SDLoc DL(N);
474  MVT Type = N->getSimpleValueType(0);
475 
476  assert(Type == MVT::i8 && "unexpected value type");
477 
478  bool isSigned = N->getOpcode() == ISD::SMUL_LOHI;
479  unsigned MachineOp = isSigned ? AVR::MULSRdRr : AVR::MULRdRr;
480 
481  SDValue Lhs = N->getOperand(0);
482  SDValue Rhs = N->getOperand(1);
483  SDNode *Mul = CurDAG->getMachineNode(MachineOp, DL, MVT::Glue, Lhs, Rhs);
484  SDValue InChain = CurDAG->getEntryNode();
485  SDValue InGlue = SDValue(Mul, 0);
486 
487  // Copy the low half of the result, if it is needed.
488  if (N->hasAnyUseOfValue(0)) {
489  SDValue CopyFromLo =
490  CurDAG->getCopyFromReg(InChain, DL, AVR::R0, Type, InGlue);
491 
492  ReplaceUses(SDValue(N, 0), CopyFromLo);
493 
494  InChain = CopyFromLo.getValue(1);
495  InGlue = CopyFromLo.getValue(2);
496  }
497 
498  // Copy the high half of the result, if it is needed.
499  if (N->hasAnyUseOfValue(1)) {
500  SDValue CopyFromHi =
501  CurDAG->getCopyFromReg(InChain, DL, AVR::R1, Type, InGlue);
502 
503  ReplaceUses(SDValue(N, 1), CopyFromHi);
504 
505  InChain = CopyFromHi.getValue(1);
506  InGlue = CopyFromHi.getValue(2);
507  }
508 
510 
511  // We need to clear R1. This is currently done (dirtily)
512  // using a custom inserter.
513 
514  return true;
515 }
516 
517 void AVRDAGToDAGISel::Select(SDNode *N) {
518  // If we have a custom node, we already have selected!
519  if (N->isMachineOpcode()) {
520  LLVM_DEBUG(errs() << "== "; N->dump(CurDAG); errs() << "\n");
521  N->setNodeId(-1);
522  return;
523  }
524 
525  // See if subclasses can handle this node.
526  if (trySelect(N))
527  return;
528 
529  // Select the default instruction
530  SelectCode(N);
531 }
532 
533 bool AVRDAGToDAGISel::trySelect(SDNode *N) {
534  unsigned Opcode = N->getOpcode();
535  SDLoc DL(N);
536 
537  switch (Opcode) {
538  // Nodes we fully handle.
539  case ISD::FrameIndex: return select<ISD::FrameIndex>(N);
540  case ISD::BRIND: return select<ISD::BRIND>(N);
541  case ISD::UMUL_LOHI:
542  case ISD::SMUL_LOHI: return selectMultiplication(N);
543 
544  // Nodes we handle partially. Other cases are autogenerated
545  case ISD::STORE: return select<ISD::STORE>(N);
546  case ISD::LOAD: return select<ISD::LOAD>(N);
547  case AVRISD::CALL: return select<AVRISD::CALL>(N);
548  default: return false;
549  }
550 }
551 
554  return new AVRDAGToDAGISel(TM, OptLevel);
555 }
556 
557 } // end of namespace llvm
558 
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...
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:1563
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)
This class represents lattice values for constants.
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.
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
unsigned Reg
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
Represents an abstract call instruction, which includes a bunch of information.
bool isProgramMemoryAccess(MemSDNode const *N)
Definition: AVR.h:48
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.
SimpleValueType SimpleTy
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:460
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:401
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:628
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:201
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:576
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.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
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:679
bool hasLPM() const
Definition: AVRSubtarget.h:64
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:705
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:206
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:614
#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)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
const SDValue & getOperand(unsigned i) const
#define LLVM_DEBUG(X)
Definition: Debug.h:123
void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand *> NewMemRefs)
Mutate the specified machine node&#39;s memory references to the provided list.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
Definition: ISDOpcodes.h:914
BRIND - Indirect branch.
Definition: ISDOpcodes.h:634
This class is used to represent ISD::LOAD nodes.