LLVM  8.0.1
ARCISelLowering.cpp
Go to the documentation of this file.
1 //===- ARCISelLowering.cpp - ARC DAG Lowering Impl --------------*- C++ -*-===//
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 implements the ARCTargetLowering class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "ARCISelLowering.h"
15 #include "ARC.h"
16 #include "ARCMachineFunctionInfo.h"
17 #include "ARCSubtarget.h"
18 #include "ARCTargetMachine.h"
19 #include "MCTargetDesc/ARCInfo.h"
28 #include "llvm/IR/CallingConv.h"
29 #include "llvm/IR/Intrinsics.h"
30 #include "llvm/Support/Debug.h"
31 #include <algorithm>
32 
33 #define DEBUG_TYPE "arc-lower"
34 
35 using namespace llvm;
36 
37 static SDValue lowerCallResult(SDValue Chain, SDValue InFlag,
38  const SmallVectorImpl<CCValAssign> &RVLocs,
39  SDLoc dl, SelectionDAG &DAG,
40  SmallVectorImpl<SDValue> &InVals);
41 
43  switch (isdCC) {
44  case ISD::SETUEQ:
45  return ARCCC::EQ;
46  case ISD::SETUGT:
47  return ARCCC::HI;
48  case ISD::SETUGE:
49  return ARCCC::HS;
50  case ISD::SETULT:
51  return ARCCC::LO;
52  case ISD::SETULE:
53  return ARCCC::LS;
54  case ISD::SETUNE:
55  return ARCCC::NE;
56  case ISD::SETEQ:
57  return ARCCC::EQ;
58  case ISD::SETGT:
59  return ARCCC::GT;
60  case ISD::SETGE:
61  return ARCCC::GE;
62  case ISD::SETLT:
63  return ARCCC::LT;
64  case ISD::SETLE:
65  return ARCCC::LE;
66  case ISD::SETNE:
67  return ARCCC::NE;
68  default:
69  llvm_unreachable("Unhandled ISDCC code.");
70  }
71 }
72 
74  const ARCSubtarget &Subtarget)
75  : TargetLowering(TM), Subtarget(Subtarget) {
76  // Set up the register classes.
77  addRegisterClass(MVT::i32, &ARC::GPR32RegClass);
78 
79  // Compute derived properties from the register classes
81 
83 
85 
86  // Use i32 for setcc operations results (slt, sgt, ...).
89 
90  for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
92 
93  // Operations to get us off of the ground.
94  // Basic.
100 
101  // Need barrel shifter.
106 
109 
110  // Need multiplier
116 
122 
123  // Have psuedo instruction for frame addresses.
125  // Custom lower global addresses.
127 
128  // Expand var-args ops.
133 
134  // Other expansions
137 
138  // Sign extend inreg
140 }
141 
142 const char *ARCTargetLowering::getTargetNodeName(unsigned Opcode) const {
143  switch (Opcode) {
144  case ARCISD::BL:
145  return "ARCISD::BL";
146  case ARCISD::CMOV:
147  return "ARCISD::CMOV";
148  case ARCISD::CMP:
149  return "ARCISD::CMP";
150  case ARCISD::BRcc:
151  return "ARCISD::BRcc";
152  case ARCISD::RET:
153  return "ARCISD::RET";
154  case ARCISD::GAWRAPPER:
155  return "ARCISD::GAWRAPPER";
156  }
157  return nullptr;
158 }
159 
160 //===----------------------------------------------------------------------===//
161 // Misc Lower Operation implementation
162 //===----------------------------------------------------------------------===//
163 
164 SDValue ARCTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
165  SDValue LHS = Op.getOperand(0);
166  SDValue RHS = Op.getOperand(1);
167  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
168  SDValue TVal = Op.getOperand(2);
169  SDValue FVal = Op.getOperand(3);
170  SDLoc dl(Op);
171  ARCCC::CondCode ArcCC = ISDCCtoARCCC(CC);
172  assert(LHS.getValueType() == MVT::i32 && "Only know how to SELECT_CC i32");
173  SDValue Cmp = DAG.getNode(ARCISD::CMP, dl, MVT::Glue, LHS, RHS);
174  return DAG.getNode(ARCISD::CMOV, dl, TVal.getValueType(), TVal, FVal,
175  DAG.getConstant(ArcCC, dl, MVT::i32), Cmp);
176 }
177 
178 SDValue ARCTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op,
179  SelectionDAG &DAG) const {
180  SDValue Op0 = Op.getOperand(0);
181  SDLoc dl(Op);
182  assert(Op.getValueType() == MVT::i32 &&
183  "Unhandled target sign_extend_inreg.");
184  // These are legal
185  unsigned Width = cast<VTSDNode>(Op.getOperand(1))->getVT().getSizeInBits();
186  if (Width == 16 || Width == 8)
187  return Op;
188  if (Width >= 32) {
189  return {};
190  }
191  SDValue LS = DAG.getNode(ISD::SHL, dl, MVT::i32, Op0,
192  DAG.getConstant(32 - Width, dl, MVT::i32));
193  SDValue SR = DAG.getNode(ISD::SRA, dl, MVT::i32, LS,
194  DAG.getConstant(32 - Width, dl, MVT::i32));
195  return SR;
196 }
197 
198 SDValue ARCTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
199  SDValue Chain = Op.getOperand(0);
200  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
201  SDValue LHS = Op.getOperand(2);
202  SDValue RHS = Op.getOperand(3);
203  SDValue Dest = Op.getOperand(4);
204  SDLoc dl(Op);
205  ARCCC::CondCode arcCC = ISDCCtoARCCC(CC);
206  assert(LHS.getValueType() == MVT::i32 && "Only know how to BR_CC i32");
207  return DAG.getNode(ARCISD::BRcc, dl, MVT::Other, Chain, Dest, LHS, RHS,
208  DAG.getConstant(arcCC, dl, MVT::i32));
209 }
210 
211 SDValue ARCTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
212  auto *N = cast<JumpTableSDNode>(Op);
213  SDValue GA = DAG.getTargetJumpTable(N->getIndex(), MVT::i32);
214  return DAG.getNode(ARCISD::GAWRAPPER, SDLoc(N), MVT::i32, GA);
215 }
216 
217 #include "ARCGenCallingConv.inc"
218 
219 //===----------------------------------------------------------------------===//
220 // Call Calling Convention Implementation
221 //===----------------------------------------------------------------------===//
222 
223 /// ARC call implementation
224 SDValue ARCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
225  SmallVectorImpl<SDValue> &InVals) const {
226  SelectionDAG &DAG = CLI.DAG;
227  SDLoc &dl = CLI.DL;
229  SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
231  SDValue Chain = CLI.Chain;
232  SDValue Callee = CLI.Callee;
233  CallingConv::ID CallConv = CLI.CallConv;
234  bool IsVarArg = CLI.IsVarArg;
235  bool &IsTailCall = CLI.IsTailCall;
236 
237  IsTailCall = false; // Do not support tail calls yet.
238 
240  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
241  *DAG.getContext());
242 
243  CCInfo.AnalyzeCallOperands(Outs, CC_ARC);
244 
246  // Analyze return values to determine the number of bytes of stack required.
247  CCState RetCCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
248  *DAG.getContext());
249  RetCCInfo.AllocateStack(CCInfo.getNextStackOffset(), 4);
250  RetCCInfo.AnalyzeCallResult(Ins, RetCC_ARC);
251 
252  // Get a count of how many bytes are to be pushed on the stack.
253  unsigned NumBytes = RetCCInfo.getNextStackOffset();
254  auto PtrVT = getPointerTy(DAG.getDataLayout());
255 
256  Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
257 
259  SmallVector<SDValue, 12> MemOpChains;
260 
261  SDValue StackPtr;
262  // Walk the register/memloc assignments, inserting copies/loads.
263  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
264  CCValAssign &VA = ArgLocs[i];
265  SDValue Arg = OutVals[i];
266 
267  // Promote the value if needed.
268  switch (VA.getLocInfo()) {
269  default:
270  llvm_unreachable("Unknown loc info!");
271  case CCValAssign::Full:
272  break;
273  case CCValAssign::SExt:
274  Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
275  break;
276  case CCValAssign::ZExt:
277  Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
278  break;
279  case CCValAssign::AExt:
280  Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
281  break;
282  }
283 
284  // Arguments that can be passed on register must be kept at
285  // RegsToPass vector
286  if (VA.isRegLoc()) {
287  RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
288  } else {
289  assert(VA.isMemLoc() && "Must be register or memory argument.");
290  if (!StackPtr.getNode())
291  StackPtr = DAG.getCopyFromReg(Chain, dl, ARC::SP,
292  getPointerTy(DAG.getDataLayout()));
293  // Calculate the stack position.
294  SDValue SOffset = DAG.getIntPtrConstant(VA.getLocMemOffset(), dl);
295  SDValue PtrOff = DAG.getNode(
296  ISD::ADD, dl, getPointerTy(DAG.getDataLayout()), StackPtr, SOffset);
297 
298  SDValue Store =
299  DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
300  MemOpChains.push_back(Store);
301  IsTailCall = false;
302  }
303  }
304 
305  // Transform all store nodes into one single node because
306  // all store nodes are independent of each other.
307  if (!MemOpChains.empty())
308  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
309 
310  // Build a sequence of copy-to-reg nodes chained together with token
311  // chain and flag operands which copy the outgoing args into registers.
312  // The InFlag in necessary since all emitted instructions must be
313  // stuck together.
314  SDValue Glue;
315  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
316  Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
317  RegsToPass[i].second, Glue);
318  Glue = Chain.getValue(1);
319  }
320 
321  // If the callee is a GlobalAddress node (quite common, every direct call is)
322  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
323  // Likewise ExternalSymbol -> TargetExternalSymbol.
324  bool IsDirect = true;
325  if (auto *G = dyn_cast<GlobalAddressSDNode>(Callee))
326  Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32);
327  else if (auto *E = dyn_cast<ExternalSymbolSDNode>(Callee))
328  Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);
329  else
330  IsDirect = false;
331  // Branch + Link = #chain, #target_address, #opt_in_flags...
332  // = Chain, Callee, Reg#1, Reg#2, ...
333  //
334  // Returns a chain & a flag for retval copy to use.
335  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
337  Ops.push_back(Chain);
338  Ops.push_back(Callee);
339 
340  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
341  Ops.push_back(DAG.getRegister(RegsToPass[i].first,
342  RegsToPass[i].second.getValueType()));
343 
344  // Add a register mask operand representing the call-preserved registers.
345  const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
346  const uint32_t *Mask =
347  TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv);
348  assert(Mask && "Missing call preserved mask for calling convention");
349  Ops.push_back(DAG.getRegisterMask(Mask));
350 
351  if (Glue.getNode())
352  Ops.push_back(Glue);
353 
354  Chain = DAG.getNode(IsDirect ? ARCISD::BL : ARCISD::JL, dl, NodeTys, Ops);
355  Glue = Chain.getValue(1);
356 
357  // Create the CALLSEQ_END node.
358  Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, dl, PtrVT, true),
359  DAG.getConstant(0, dl, PtrVT, true), Glue, dl);
360  Glue = Chain.getValue(1);
361 
362  // Handle result values, copying them out of physregs into vregs that we
363  // return.
364  if (IsTailCall)
365  return Chain;
366  return lowerCallResult(Chain, Glue, RVLocs, dl, DAG, InVals);
367 }
368 
369 /// Lower the result values of a call into the appropriate copies out of
370 /// physical registers / memory locations.
372  const SmallVectorImpl<CCValAssign> &RVLocs,
373  SDLoc dl, SelectionDAG &DAG,
374  SmallVectorImpl<SDValue> &InVals) {
375  SmallVector<std::pair<int, unsigned>, 4> ResultMemLocs;
376  // Copy results out of physical registers.
377  for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
378  const CCValAssign &VA = RVLocs[i];
379  if (VA.isRegLoc()) {
380  SDValue RetValue;
381  RetValue =
382  DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getValVT(), Glue);
383  Chain = RetValue.getValue(1);
384  Glue = RetValue.getValue(2);
385  InVals.push_back(RetValue);
386  } else {
387  assert(VA.isMemLoc() && "Must be memory location.");
388  ResultMemLocs.push_back(
389  std::make_pair(VA.getLocMemOffset(), InVals.size()));
390 
391  // Reserve space for this result.
392  InVals.push_back(SDValue());
393  }
394  }
395 
396  // Copy results out of memory.
397  SmallVector<SDValue, 4> MemOpChains;
398  for (unsigned i = 0, e = ResultMemLocs.size(); i != e; ++i) {
399  int Offset = ResultMemLocs[i].first;
400  unsigned Index = ResultMemLocs[i].second;
401  SDValue StackPtr = DAG.getRegister(ARC::SP, MVT::i32);
402  SDValue SpLoc = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr,
403  DAG.getConstant(Offset, dl, MVT::i32));
404  SDValue Load =
405  DAG.getLoad(MVT::i32, dl, Chain, SpLoc, MachinePointerInfo());
406  InVals[Index] = Load;
407  MemOpChains.push_back(Load.getValue(1));
408  }
409 
410  // Transform all loads nodes into one single node because
411  // all load nodes are independent of each other.
412  if (!MemOpChains.empty())
413  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
414 
415  return Chain;
416 }
417 
418 //===----------------------------------------------------------------------===//
419 // Formal Arguments Calling Convention Implementation
420 //===----------------------------------------------------------------------===//
421 
422 namespace {
423 
424 struct ArgDataPair {
425  SDValue SDV;
426  ISD::ArgFlagsTy Flags;
427 };
428 
429 } // end anonymous namespace
430 
431 /// ARC formal arguments implementation
432 SDValue ARCTargetLowering::LowerFormalArguments(
433  SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
434  const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
435  SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
436  switch (CallConv) {
437  default:
438  llvm_unreachable("Unsupported calling convention");
439  case CallingConv::C:
440  case CallingConv::Fast:
441  return LowerCallArguments(Chain, CallConv, IsVarArg, Ins, dl, DAG, InVals);
442  }
443 }
444 
445 /// Transform physical registers into virtual registers, and generate load
446 /// operations for argument places on the stack.
447 SDValue ARCTargetLowering::LowerCallArguments(
448  SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
450  SmallVectorImpl<SDValue> &InVals) const {
452  MachineFrameInfo &MFI = MF.getFrameInfo();
453  MachineRegisterInfo &RegInfo = MF.getRegInfo();
454  auto *AFI = MF.getInfo<ARCFunctionInfo>();
455 
456  // Assign locations to all of the incoming arguments.
458  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
459  *DAG.getContext());
460 
461  CCInfo.AnalyzeFormalArguments(Ins, CC_ARC);
462 
463  unsigned StackSlotSize = 4;
464 
465  if (!IsVarArg)
466  AFI->setReturnStackOffset(CCInfo.getNextStackOffset());
467 
468  // All getCopyFromReg ops must precede any getMemcpys to prevent the
469  // scheduler clobbering a register before it has been copied.
470  // The stages are:
471  // 1. CopyFromReg (and load) arg & vararg registers.
472  // 2. Chain CopyFromReg nodes into a TokenFactor.
473  // 3. Memcpy 'byVal' args & push final InVals.
474  // 4. Chain mem ops nodes into a TokenFactor.
475  SmallVector<SDValue, 4> CFRegNode;
478 
479  // 1a. CopyFromReg (and load) arg registers.
480  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
481  CCValAssign &VA = ArgLocs[i];
482  SDValue ArgIn;
483 
484  if (VA.isRegLoc()) {
485  // Arguments passed in registers
486  EVT RegVT = VA.getLocVT();
487  switch (RegVT.getSimpleVT().SimpleTy) {
488  default: {
489  LLVM_DEBUG(errs() << "LowerFormalArguments Unhandled argument type: "
490  << (unsigned)RegVT.getSimpleVT().SimpleTy << "\n");
491  llvm_unreachable("Unhandled LowerFormalArguments type.");
492  }
493  case MVT::i32:
494  unsigned VReg = RegInfo.createVirtualRegister(&ARC::GPR32RegClass);
495  RegInfo.addLiveIn(VA.getLocReg(), VReg);
496  ArgIn = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
497  CFRegNode.push_back(ArgIn.getValue(ArgIn->getNumValues() - 1));
498  }
499  } else {
500  // sanity check
501  assert(VA.isMemLoc());
502  // Load the argument to a virtual register
503  unsigned ObjSize = VA.getLocVT().getStoreSize();
504  assert((ObjSize <= StackSlotSize) && "Unhandled argument");
505 
506  // Create the frame index object for this incoming parameter...
507  int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
508 
509  // Create the SelectionDAG nodes corresponding to a load
510  // from this parameter
511  SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
512  ArgIn = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
514  }
515  const ArgDataPair ADP = {ArgIn, Ins[i].Flags};
516  ArgData.push_back(ADP);
517  }
518 
519  // 1b. CopyFromReg vararg registers.
520  if (IsVarArg) {
521  // Argument registers
522  static const MCPhysReg ArgRegs[] = {ARC::R0, ARC::R1, ARC::R2, ARC::R3,
523  ARC::R4, ARC::R5, ARC::R6, ARC::R7};
524  auto *AFI = MF.getInfo<ARCFunctionInfo>();
525  unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs);
526  if (FirstVAReg < array_lengthof(ArgRegs)) {
527  int Offset = 0;
528  // Save remaining registers, storing higher register numbers at a higher
529  // address
530  // There are (array_lengthof(ArgRegs) - FirstVAReg) registers which
531  // need to be saved.
532  int VarFI =
533  MFI.CreateFixedObject((array_lengthof(ArgRegs) - FirstVAReg) * 4,
534  CCInfo.getNextStackOffset(), true);
535  AFI->setVarArgsFrameIndex(VarFI);
536  SDValue FIN = DAG.getFrameIndex(VarFI, MVT::i32);
537  for (unsigned i = FirstVAReg; i < array_lengthof(ArgRegs); i++) {
538  // Move argument from phys reg -> virt reg
539  unsigned VReg = RegInfo.createVirtualRegister(&ARC::GPR32RegClass);
540  RegInfo.addLiveIn(ArgRegs[i], VReg);
541  SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
542  CFRegNode.push_back(Val.getValue(Val->getNumValues() - 1));
543  SDValue VAObj = DAG.getNode(ISD::ADD, dl, MVT::i32, FIN,
544  DAG.getConstant(Offset, dl, MVT::i32));
545  // Move argument from virt reg -> stack
546  SDValue Store =
547  DAG.getStore(Val.getValue(1), dl, Val, VAObj, MachinePointerInfo());
548  MemOps.push_back(Store);
549  Offset += 4;
550  }
551  } else {
552  llvm_unreachable("Too many var args parameters.");
553  }
554  }
555 
556  // 2. Chain CopyFromReg nodes into a TokenFactor.
557  if (!CFRegNode.empty())
558  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, CFRegNode);
559 
560  // 3. Memcpy 'byVal' args & push final InVals.
561  // Aggregates passed "byVal" need to be copied by the callee.
562  // The callee will use a pointer to this copy, rather than the original
563  // pointer.
564  for (const auto &ArgDI : ArgData) {
565  if (ArgDI.Flags.isByVal() && ArgDI.Flags.getByValSize()) {
566  unsigned Size = ArgDI.Flags.getByValSize();
567  unsigned Align = std::max(StackSlotSize, ArgDI.Flags.getByValAlign());
568  // Create a new object on the stack and copy the pointee into it.
569  int FI = MFI.CreateStackObject(Size, Align, false);
570  SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
571  InVals.push_back(FIN);
572  MemOps.push_back(DAG.getMemcpy(
573  Chain, dl, FIN, ArgDI.SDV, DAG.getConstant(Size, dl, MVT::i32), Align,
574  false, false, false, MachinePointerInfo(), MachinePointerInfo()));
575  } else {
576  InVals.push_back(ArgDI.SDV);
577  }
578  }
579 
580  // 4. Chain mem ops nodes into a TokenFactor.
581  if (!MemOps.empty()) {
582  MemOps.push_back(Chain);
583  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps);
584  }
585 
586  return Chain;
587 }
588 
589 //===----------------------------------------------------------------------===//
590 // Return Value Calling Convention Implementation
591 //===----------------------------------------------------------------------===//
592 
593 bool ARCTargetLowering::CanLowerReturn(
594  CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
597  CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
598  if (!CCInfo.CheckReturn(Outs, RetCC_ARC))
599  return false;
600  if (CCInfo.getNextStackOffset() != 0 && IsVarArg)
601  return false;
602  return true;
603 }
604 
605 SDValue
606 ARCTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
607  bool IsVarArg,
609  const SmallVectorImpl<SDValue> &OutVals,
610  const SDLoc &dl, SelectionDAG &DAG) const {
611  auto *AFI = DAG.getMachineFunction().getInfo<ARCFunctionInfo>();
613 
614  // CCValAssign - represent the assignment of
615  // the return value to a location
617 
618  // CCState - Info about the registers and stack slot.
619  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
620  *DAG.getContext());
621 
622  // Analyze return values.
623  if (!IsVarArg)
624  CCInfo.AllocateStack(AFI->getReturnStackOffset(), 4);
625 
626  CCInfo.AnalyzeReturn(Outs, RetCC_ARC);
627 
628  SDValue Flag;
629  SmallVector<SDValue, 4> RetOps(1, Chain);
630  SmallVector<SDValue, 4> MemOpChains;
631  // Handle return values that must be copied to memory.
632  for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
633  CCValAssign &VA = RVLocs[i];
634  if (VA.isRegLoc())
635  continue;
636  assert(VA.isMemLoc());
637  if (IsVarArg) {
638  report_fatal_error("Can't return value from vararg function in memory");
639  }
640 
641  int Offset = VA.getLocMemOffset();
642  unsigned ObjSize = VA.getLocVT().getStoreSize();
643  // Create the frame index object for the memory location.
644  int FI = MFI.CreateFixedObject(ObjSize, Offset, false);
645 
646  // Create a SelectionDAG node corresponding to a store
647  // to this memory location.
648  SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
649  MemOpChains.push_back(DAG.getStore(
650  Chain, dl, OutVals[i], FIN,
652  }
653 
654  // Transform all store nodes into one single node because
655  // all stores are independent of each other.
656  if (!MemOpChains.empty())
657  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
658 
659  // Now handle return values copied to registers.
660  for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
661  CCValAssign &VA = RVLocs[i];
662  if (!VA.isRegLoc())
663  continue;
664  // Copy the result values into the output registers.
665  Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Flag);
666 
667  // guarantee that all emitted copies are
668  // stuck together, avoiding something bad
669  Flag = Chain.getValue(1);
670  RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
671  }
672 
673  RetOps[0] = Chain; // Update chain.
674 
675  // Add the flag if we have it.
676  if (Flag.getNode())
677  RetOps.push_back(Flag);
678 
679  // What to do with the RetOps?
680  return DAG.getNode(ARCISD::RET, dl, MVT::Other, RetOps);
681 }
682 
683 //===----------------------------------------------------------------------===//
684 // Target Optimization Hooks
685 //===----------------------------------------------------------------------===//
686 
687 SDValue ARCTargetLowering::PerformDAGCombine(SDNode *N,
688  DAGCombinerInfo &DCI) const {
689  return {};
690 }
691 
692 //===----------------------------------------------------------------------===//
693 // Addressing mode description hooks
694 //===----------------------------------------------------------------------===//
695 
696 /// Return true if the addressing mode represented by AM is legal for this
697 /// target, for a load/store of the specified type.
699  const AddrMode &AM, Type *Ty,
700  unsigned AS,
701  Instruction *I) const {
702  return AM.Scale == 0;
703 }
704 
705 // Don't emit tail calls for the time being.
706 bool ARCTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
707  return false;
708 }
709 
710 SDValue ARCTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
711  const ARCRegisterInfo &ARI = *Subtarget.getRegisterInfo();
713  MachineFrameInfo &MFI = MF.getFrameInfo();
714  MFI.setFrameAddressIsTaken(true);
715 
716  EVT VT = Op.getValueType();
717  SDLoc dl(Op);
718  assert(cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0 &&
719  "Only support lowering frame addr of current frame.");
720  unsigned FrameReg = ARI.getFrameRegister(MF);
721  return DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
722 }
723 
724 SDValue ARCTargetLowering::LowerGlobalAddress(SDValue Op,
725  SelectionDAG &DAG) const {
726  const GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op);
727  const GlobalValue *GV = GN->getGlobal();
728  SDLoc dl(GN);
729  int64_t Offset = GN->getOffset();
730  SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, Offset);
731  return DAG.getNode(ARCISD::GAWRAPPER, dl, MVT::i32, GA);
732 }
733 
736  auto *FuncInfo = MF.getInfo<ARCFunctionInfo>();
737 
738  // vastart just stores the address of the VarArgsFrameIndex slot into the
739  // memory location argument.
740  SDLoc dl(Op);
742  SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
743  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
744  return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1),
745  MachinePointerInfo(SV));
746 }
747 
749  switch (Op.getOpcode()) {
750  case ISD::GlobalAddress:
751  return LowerGlobalAddress(Op, DAG);
752  case ISD::FRAMEADDR:
753  return LowerFRAMEADDR(Op, DAG);
754  case ISD::SELECT_CC:
755  return LowerSELECT_CC(Op, DAG);
756  case ISD::BR_CC:
757  return LowerBR_CC(Op, DAG);
759  return LowerSIGN_EXTEND_INREG(Op, DAG);
760  case ISD::JumpTable:
761  return LowerJumpTable(Op, DAG);
762  case ISD::VASTART:
763  return LowerVASTART(Op, DAG);
764  default:
765  llvm_unreachable("unimplemented operand");
766  }
767 }
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
void setFrameAddressIsTaken(bool T)
ARCFunctionInfo - This class is derived from MachineFunction private ARC target-specific information ...
BUILTIN_OP_END - This must be the last enum value in this list.
Definition: ISDOpcodes.h:877
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:111
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
EVT getValueType() const
Return the ValueType of the referenced return value.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg If BaseGV is null...
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
C - The default llvm calling convention, compatible with C.
Definition: CallingConv.h:35
const GlobalValue * getGlobal() const
#define R4(n)
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
LLVMContext & Context
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it&#39;s not CSE&#39;d)...
Definition: SelectionDAG.h:836
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:650
This class represents lattice values for constants.
Definition: AllocatorList.h:24
void addLiveIn(unsigned Reg, unsigned vreg=0)
addLiveIn - Add the specified register as a live-in.
void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain...
Definition: ISDOpcodes.h:699
ARCTargetLowering(const TargetMachine &TM, const ARCSubtarget &Subtarget)
This class represents a function call, abstracting a target machine&#39;s calling convention.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:253
unsigned second
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
unsigned const TargetRegisterInfo * TRI
static SDValue lowerCallResult(SDValue Chain, SDValue InFlag, const SmallVectorImpl< CCValAssign > &RVLocs, SDLoc dl, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals)
Lower the result values of a call into the appropriate copies out of physical registers / memory loca...
[US]{MIN/MAX} - Binary minimum or maximum or signed or unsigned integers.
Definition: ISDOpcodes.h:384
#define R2(n)
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned char TargetFlags=0)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
Provide custom lowering hooks for some operations.
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it...
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:435
unsigned getFrameRegister(const MachineFunction &MF) const override
bool isMemLoc() const
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
Shift and rotation operations.
Definition: ISDOpcodes.h:410
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
SimpleValueType SimpleTy
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:460
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:401
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG...
Definition: ISDOpcodes.h:73
unsigned getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
LocInfo getLocInfo() const
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
This represents a list of ValueType&#39;s that has been intern&#39;d by a SelectionDAG.
SmallVector< ISD::InputArg, 32 > Ins
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:695
const ARCRegisterInfo * getRegisterInfo() const override
Definition: ARCSubtarget.h:56
Fast - This calling convention attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:43
unsigned getNextStackOffset() const
getNextStackOffset - Return the next stack offset such that all stack slots satisfy their alignment r...
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:398
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose...
SDValue getRegisterMask(const uint32_t *RegMask)
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:201
SmallVector< ISD::OutputArg, 32 > Outs
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
Definition: ISDOpcodes.h:959
amdgpu Simplify well known AMD library false Value * Callee
UNDEF - An undefined node.
Definition: ISDOpcodes.h:178
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:118
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
virtual const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const
Return a mask of call-preserved registers for the given calling convention on the current function...
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...
static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG)
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:69
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type...
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE...
Definition: ISDOpcodes.h:728
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
Definition: SelectionDAG.h:824
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:719
Extended Value Type.
Definition: ValueTypes.h:34
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This structure contains all information that is necessary for lowering calls.
size_t size() const
Definition: SmallVector.h:53
This class contains a discriminated union of information about pointers in memory operands...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands...
unsigned first
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned char TargetFlags=0)
Definition: SelectionDAG.h:633
TokenFactor - This node takes multiple tokens as input and produces a single token result...
Definition: ISDOpcodes.h:50
const TargetLowering & getTargetLoweringInfo() const
Definition: SelectionDAG.h:404
CCState - This class holds information needed while lowering arguments and return values...
#define R6(n)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:222
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
CCValAssign - Represent assignment of one arg/retval to a location.
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo)
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:1044
BRCOND - Conditional branch.
Definition: ISDOpcodes.h:644
const DataFlowGraph & G
Definition: RDFGraph.cpp:211
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:679
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
static ARCCC::CondCode ISDCCtoARCCC(ISD::CondCode isdCC)
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:468
void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:471
amdgpu Simplify well known AMD library false Value Value * Arg
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:638
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the source.
Definition: ISDOpcodes.h:724
SmallVector< SDValue, 32 > OutVals
bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:387
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.
unsigned getLocMemOffset() const
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:56
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:486
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:614
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
void setStackPointerRegisterToSaveRestore(unsigned R)
If set to a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save and restore.
uint32_t Size
Definition: Profile.cpp:47
unsigned getOpcode() const
SDValue getValue(unsigned R) const
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
bool isRegLoc() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
LLVM Value Representation.
Definition: Value.h:73
SDValue getRegister(unsigned Reg, EVT VT)
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:81
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:59
Conversion operators.
Definition: ISDOpcodes.h:465
const SDValue & getOperand(unsigned i) const
unsigned getLocReg() const
#define LLVM_DEBUG(X)
Definition: Debug.h:123
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
unsigned AllocateStack(unsigned Size, unsigned Align)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
LLVMContext * getContext() const
Definition: SelectionDAG.h:407
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned char TargetFlags=0)
Definition: SelectionDAG.h:622
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:380