LLVM  9.0.0svn
ARCISelLowering.cpp
Go to the documentation of this file.
1 //===- ARCISelLowering.cpp - ARC DAG Lowering Impl --------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the ARCTargetLowering class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "ARCISelLowering.h"
14 #include "ARC.h"
15 #include "ARCMachineFunctionInfo.h"
16 #include "ARCSubtarget.h"
17 #include "ARCTargetMachine.h"
18 #include "MCTargetDesc/ARCInfo.h"
27 #include "llvm/IR/CallingConv.h"
28 #include "llvm/IR/Intrinsics.h"
29 #include "llvm/Support/Debug.h"
30 #include <algorithm>
31 
32 #define DEBUG_TYPE "arc-lower"
33 
34 using namespace llvm;
35 
36 static SDValue lowerCallResult(SDValue Chain, SDValue InFlag,
37  const SmallVectorImpl<CCValAssign> &RVLocs,
38  SDLoc dl, SelectionDAG &DAG,
39  SmallVectorImpl<SDValue> &InVals);
40 
42  switch (isdCC) {
43  case ISD::SETUEQ:
44  return ARCCC::EQ;
45  case ISD::SETUGT:
46  return ARCCC::HI;
47  case ISD::SETUGE:
48  return ARCCC::HS;
49  case ISD::SETULT:
50  return ARCCC::LO;
51  case ISD::SETULE:
52  return ARCCC::LS;
53  case ISD::SETUNE:
54  return ARCCC::NE;
55  case ISD::SETEQ:
56  return ARCCC::EQ;
57  case ISD::SETGT:
58  return ARCCC::GT;
59  case ISD::SETGE:
60  return ARCCC::GE;
61  case ISD::SETLT:
62  return ARCCC::LT;
63  case ISD::SETLE:
64  return ARCCC::LE;
65  case ISD::SETNE:
66  return ARCCC::NE;
67  default:
68  llvm_unreachable("Unhandled ISDCC code.");
69  }
70 }
71 
73  const ARCSubtarget &Subtarget)
74  : TargetLowering(TM), Subtarget(Subtarget) {
75  // Set up the register classes.
76  addRegisterClass(MVT::i32, &ARC::GPR32RegClass);
77 
78  // Compute derived properties from the register classes
80 
82 
84 
85  // Use i32 for setcc operations results (slt, sgt, ...).
88 
89  for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
91 
92  // Operations to get us off of the ground.
93  // Basic.
99 
100  // Need barrel shifter.
105 
108 
109  // Need multiplier
115 
121 
122  // Have psuedo instruction for frame addresses.
124  // Custom lower global addresses.
126 
127  // Expand var-args ops.
132 
133  // Other expansions
136 
137  // Sign extend inreg
139 }
140 
141 const char *ARCTargetLowering::getTargetNodeName(unsigned Opcode) const {
142  switch (Opcode) {
143  case ARCISD::BL:
144  return "ARCISD::BL";
145  case ARCISD::CMOV:
146  return "ARCISD::CMOV";
147  case ARCISD::CMP:
148  return "ARCISD::CMP";
149  case ARCISD::BRcc:
150  return "ARCISD::BRcc";
151  case ARCISD::RET:
152  return "ARCISD::RET";
153  case ARCISD::GAWRAPPER:
154  return "ARCISD::GAWRAPPER";
155  }
156  return nullptr;
157 }
158 
159 //===----------------------------------------------------------------------===//
160 // Misc Lower Operation implementation
161 //===----------------------------------------------------------------------===//
162 
163 SDValue ARCTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
164  SDValue LHS = Op.getOperand(0);
165  SDValue RHS = Op.getOperand(1);
166  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
167  SDValue TVal = Op.getOperand(2);
168  SDValue FVal = Op.getOperand(3);
169  SDLoc dl(Op);
170  ARCCC::CondCode ArcCC = ISDCCtoARCCC(CC);
171  assert(LHS.getValueType() == MVT::i32 && "Only know how to SELECT_CC i32");
172  SDValue Cmp = DAG.getNode(ARCISD::CMP, dl, MVT::Glue, LHS, RHS);
173  return DAG.getNode(ARCISD::CMOV, dl, TVal.getValueType(), TVal, FVal,
174  DAG.getConstant(ArcCC, dl, MVT::i32), Cmp);
175 }
176 
177 SDValue ARCTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op,
178  SelectionDAG &DAG) const {
179  SDValue Op0 = Op.getOperand(0);
180  SDLoc dl(Op);
181  assert(Op.getValueType() == MVT::i32 &&
182  "Unhandled target sign_extend_inreg.");
183  // These are legal
184  unsigned Width = cast<VTSDNode>(Op.getOperand(1))->getVT().getSizeInBits();
185  if (Width == 16 || Width == 8)
186  return Op;
187  if (Width >= 32) {
188  return {};
189  }
190  SDValue LS = DAG.getNode(ISD::SHL, dl, MVT::i32, Op0,
191  DAG.getConstant(32 - Width, dl, MVT::i32));
192  SDValue SR = DAG.getNode(ISD::SRA, dl, MVT::i32, LS,
193  DAG.getConstant(32 - Width, dl, MVT::i32));
194  return SR;
195 }
196 
197 SDValue ARCTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
198  SDValue Chain = Op.getOperand(0);
199  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
200  SDValue LHS = Op.getOperand(2);
201  SDValue RHS = Op.getOperand(3);
202  SDValue Dest = Op.getOperand(4);
203  SDLoc dl(Op);
204  ARCCC::CondCode arcCC = ISDCCtoARCCC(CC);
205  assert(LHS.getValueType() == MVT::i32 && "Only know how to BR_CC i32");
206  return DAG.getNode(ARCISD::BRcc, dl, MVT::Other, Chain, Dest, LHS, RHS,
207  DAG.getConstant(arcCC, dl, MVT::i32));
208 }
209 
210 SDValue ARCTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
211  auto *N = cast<JumpTableSDNode>(Op);
212  SDValue GA = DAG.getTargetJumpTable(N->getIndex(), MVT::i32);
213  return DAG.getNode(ARCISD::GAWRAPPER, SDLoc(N), MVT::i32, GA);
214 }
215 
216 #include "ARCGenCallingConv.inc"
217 
218 //===----------------------------------------------------------------------===//
219 // Call Calling Convention Implementation
220 //===----------------------------------------------------------------------===//
221 
222 /// ARC call implementation
223 SDValue ARCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
224  SmallVectorImpl<SDValue> &InVals) const {
225  SelectionDAG &DAG = CLI.DAG;
226  SDLoc &dl = CLI.DL;
228  SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
230  SDValue Chain = CLI.Chain;
231  SDValue Callee = CLI.Callee;
232  CallingConv::ID CallConv = CLI.CallConv;
233  bool IsVarArg = CLI.IsVarArg;
234  bool &IsTailCall = CLI.IsTailCall;
235 
236  IsTailCall = false; // Do not support tail calls yet.
237 
239  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
240  *DAG.getContext());
241 
242  CCInfo.AnalyzeCallOperands(Outs, CC_ARC);
243 
245  // Analyze return values to determine the number of bytes of stack required.
246  CCState RetCCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
247  *DAG.getContext());
248  RetCCInfo.AllocateStack(CCInfo.getNextStackOffset(), 4);
249  RetCCInfo.AnalyzeCallResult(Ins, RetCC_ARC);
250 
251  // Get a count of how many bytes are to be pushed on the stack.
252  unsigned NumBytes = RetCCInfo.getNextStackOffset();
253  auto PtrVT = getPointerTy(DAG.getDataLayout());
254 
255  Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
256 
258  SmallVector<SDValue, 12> MemOpChains;
259 
260  SDValue StackPtr;
261  // Walk the register/memloc assignments, inserting copies/loads.
262  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
263  CCValAssign &VA = ArgLocs[i];
264  SDValue Arg = OutVals[i];
265 
266  // Promote the value if needed.
267  switch (VA.getLocInfo()) {
268  default:
269  llvm_unreachable("Unknown loc info!");
270  case CCValAssign::Full:
271  break;
272  case CCValAssign::SExt:
273  Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
274  break;
275  case CCValAssign::ZExt:
276  Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
277  break;
278  case CCValAssign::AExt:
279  Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
280  break;
281  }
282 
283  // Arguments that can be passed on register must be kept at
284  // RegsToPass vector
285  if (VA.isRegLoc()) {
286  RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
287  } else {
288  assert(VA.isMemLoc() && "Must be register or memory argument.");
289  if (!StackPtr.getNode())
290  StackPtr = DAG.getCopyFromReg(Chain, dl, ARC::SP,
291  getPointerTy(DAG.getDataLayout()));
292  // Calculate the stack position.
293  SDValue SOffset = DAG.getIntPtrConstant(VA.getLocMemOffset(), dl);
294  SDValue PtrOff = DAG.getNode(
295  ISD::ADD, dl, getPointerTy(DAG.getDataLayout()), StackPtr, SOffset);
296 
297  SDValue Store =
298  DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
299  MemOpChains.push_back(Store);
300  IsTailCall = false;
301  }
302  }
303 
304  // Transform all store nodes into one single node because
305  // all store nodes are independent of each other.
306  if (!MemOpChains.empty())
307  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
308 
309  // Build a sequence of copy-to-reg nodes chained together with token
310  // chain and flag operands which copy the outgoing args into registers.
311  // The InFlag in necessary since all emitted instructions must be
312  // stuck together.
313  SDValue Glue;
314  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
315  Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
316  RegsToPass[i].second, Glue);
317  Glue = Chain.getValue(1);
318  }
319 
320  // If the callee is a GlobalAddress node (quite common, every direct call is)
321  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
322  // Likewise ExternalSymbol -> TargetExternalSymbol.
323  bool IsDirect = true;
324  if (auto *G = dyn_cast<GlobalAddressSDNode>(Callee))
325  Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32);
326  else if (auto *E = dyn_cast<ExternalSymbolSDNode>(Callee))
327  Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);
328  else
329  IsDirect = false;
330  // Branch + Link = #chain, #target_address, #opt_in_flags...
331  // = Chain, Callee, Reg#1, Reg#2, ...
332  //
333  // Returns a chain & a flag for retval copy to use.
334  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
336  Ops.push_back(Chain);
337  Ops.push_back(Callee);
338 
339  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
340  Ops.push_back(DAG.getRegister(RegsToPass[i].first,
341  RegsToPass[i].second.getValueType()));
342 
343  // Add a register mask operand representing the call-preserved registers.
344  const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
345  const uint32_t *Mask =
346  TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv);
347  assert(Mask && "Missing call preserved mask for calling convention");
348  Ops.push_back(DAG.getRegisterMask(Mask));
349 
350  if (Glue.getNode())
351  Ops.push_back(Glue);
352 
353  Chain = DAG.getNode(IsDirect ? ARCISD::BL : ARCISD::JL, dl, NodeTys, Ops);
354  Glue = Chain.getValue(1);
355 
356  // Create the CALLSEQ_END node.
357  Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, dl, PtrVT, true),
358  DAG.getConstant(0, dl, PtrVT, true), Glue, dl);
359  Glue = Chain.getValue(1);
360 
361  // Handle result values, copying them out of physregs into vregs that we
362  // return.
363  if (IsTailCall)
364  return Chain;
365  return lowerCallResult(Chain, Glue, RVLocs, dl, DAG, InVals);
366 }
367 
368 /// Lower the result values of a call into the appropriate copies out of
369 /// physical registers / memory locations.
371  const SmallVectorImpl<CCValAssign> &RVLocs,
372  SDLoc dl, SelectionDAG &DAG,
373  SmallVectorImpl<SDValue> &InVals) {
374  SmallVector<std::pair<int, unsigned>, 4> ResultMemLocs;
375  // Copy results out of physical registers.
376  for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
377  const CCValAssign &VA = RVLocs[i];
378  if (VA.isRegLoc()) {
379  SDValue RetValue;
380  RetValue =
381  DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getValVT(), Glue);
382  Chain = RetValue.getValue(1);
383  Glue = RetValue.getValue(2);
384  InVals.push_back(RetValue);
385  } else {
386  assert(VA.isMemLoc() && "Must be memory location.");
387  ResultMemLocs.push_back(
388  std::make_pair(VA.getLocMemOffset(), InVals.size()));
389 
390  // Reserve space for this result.
391  InVals.push_back(SDValue());
392  }
393  }
394 
395  // Copy results out of memory.
396  SmallVector<SDValue, 4> MemOpChains;
397  for (unsigned i = 0, e = ResultMemLocs.size(); i != e; ++i) {
398  int Offset = ResultMemLocs[i].first;
399  unsigned Index = ResultMemLocs[i].second;
400  SDValue StackPtr = DAG.getRegister(ARC::SP, MVT::i32);
401  SDValue SpLoc = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr,
402  DAG.getConstant(Offset, dl, MVT::i32));
403  SDValue Load =
404  DAG.getLoad(MVT::i32, dl, Chain, SpLoc, MachinePointerInfo());
405  InVals[Index] = Load;
406  MemOpChains.push_back(Load.getValue(1));
407  }
408 
409  // Transform all loads nodes into one single node because
410  // all load nodes are independent of each other.
411  if (!MemOpChains.empty())
412  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
413 
414  return Chain;
415 }
416 
417 //===----------------------------------------------------------------------===//
418 // Formal Arguments Calling Convention Implementation
419 //===----------------------------------------------------------------------===//
420 
421 namespace {
422 
423 struct ArgDataPair {
424  SDValue SDV;
425  ISD::ArgFlagsTy Flags;
426 };
427 
428 } // end anonymous namespace
429 
430 /// ARC formal arguments implementation
431 SDValue ARCTargetLowering::LowerFormalArguments(
432  SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
433  const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
434  SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
435  switch (CallConv) {
436  default:
437  llvm_unreachable("Unsupported calling convention");
438  case CallingConv::C:
439  case CallingConv::Fast:
440  return LowerCallArguments(Chain, CallConv, IsVarArg, Ins, dl, DAG, InVals);
441  }
442 }
443 
444 /// Transform physical registers into virtual registers, and generate load
445 /// operations for argument places on the stack.
446 SDValue ARCTargetLowering::LowerCallArguments(
447  SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
449  SmallVectorImpl<SDValue> &InVals) const {
451  MachineFrameInfo &MFI = MF.getFrameInfo();
452  MachineRegisterInfo &RegInfo = MF.getRegInfo();
453  auto *AFI = MF.getInfo<ARCFunctionInfo>();
454 
455  // Assign locations to all of the incoming arguments.
457  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
458  *DAG.getContext());
459 
460  CCInfo.AnalyzeFormalArguments(Ins, CC_ARC);
461 
462  unsigned StackSlotSize = 4;
463 
464  if (!IsVarArg)
465  AFI->setReturnStackOffset(CCInfo.getNextStackOffset());
466 
467  // All getCopyFromReg ops must precede any getMemcpys to prevent the
468  // scheduler clobbering a register before it has been copied.
469  // The stages are:
470  // 1. CopyFromReg (and load) arg & vararg registers.
471  // 2. Chain CopyFromReg nodes into a TokenFactor.
472  // 3. Memcpy 'byVal' args & push final InVals.
473  // 4. Chain mem ops nodes into a TokenFactor.
474  SmallVector<SDValue, 4> CFRegNode;
477 
478  // 1a. CopyFromReg (and load) arg registers.
479  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
480  CCValAssign &VA = ArgLocs[i];
481  SDValue ArgIn;
482 
483  if (VA.isRegLoc()) {
484  // Arguments passed in registers
485  EVT RegVT = VA.getLocVT();
486  switch (RegVT.getSimpleVT().SimpleTy) {
487  default: {
488  LLVM_DEBUG(errs() << "LowerFormalArguments Unhandled argument type: "
489  << (unsigned)RegVT.getSimpleVT().SimpleTy << "\n");
490  llvm_unreachable("Unhandled LowerFormalArguments type.");
491  }
492  case MVT::i32:
493  unsigned VReg = RegInfo.createVirtualRegister(&ARC::GPR32RegClass);
494  RegInfo.addLiveIn(VA.getLocReg(), VReg);
495  ArgIn = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
496  CFRegNode.push_back(ArgIn.getValue(ArgIn->getNumValues() - 1));
497  }
498  } else {
499  // sanity check
500  assert(VA.isMemLoc());
501  // Load the argument to a virtual register
502  unsigned ObjSize = VA.getLocVT().getStoreSize();
503  assert((ObjSize <= StackSlotSize) && "Unhandled argument");
504 
505  // Create the frame index object for this incoming parameter...
506  int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
507 
508  // Create the SelectionDAG nodes corresponding to a load
509  // from this parameter
510  SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
511  ArgIn = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
513  }
514  const ArgDataPair ADP = {ArgIn, Ins[i].Flags};
515  ArgData.push_back(ADP);
516  }
517 
518  // 1b. CopyFromReg vararg registers.
519  if (IsVarArg) {
520  // Argument registers
521  static const MCPhysReg ArgRegs[] = {ARC::R0, ARC::R1, ARC::R2, ARC::R3,
522  ARC::R4, ARC::R5, ARC::R6, ARC::R7};
523  auto *AFI = MF.getInfo<ARCFunctionInfo>();
524  unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs);
525  if (FirstVAReg < array_lengthof(ArgRegs)) {
526  int Offset = 0;
527  // Save remaining registers, storing higher register numbers at a higher
528  // address
529  // There are (array_lengthof(ArgRegs) - FirstVAReg) registers which
530  // need to be saved.
531  int VarFI =
532  MFI.CreateFixedObject((array_lengthof(ArgRegs) - FirstVAReg) * 4,
533  CCInfo.getNextStackOffset(), true);
534  AFI->setVarArgsFrameIndex(VarFI);
535  SDValue FIN = DAG.getFrameIndex(VarFI, MVT::i32);
536  for (unsigned i = FirstVAReg; i < array_lengthof(ArgRegs); i++) {
537  // Move argument from phys reg -> virt reg
538  unsigned VReg = RegInfo.createVirtualRegister(&ARC::GPR32RegClass);
539  RegInfo.addLiveIn(ArgRegs[i], VReg);
540  SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
541  CFRegNode.push_back(Val.getValue(Val->getNumValues() - 1));
542  SDValue VAObj = DAG.getNode(ISD::ADD, dl, MVT::i32, FIN,
543  DAG.getConstant(Offset, dl, MVT::i32));
544  // Move argument from virt reg -> stack
545  SDValue Store =
546  DAG.getStore(Val.getValue(1), dl, Val, VAObj, MachinePointerInfo());
547  MemOps.push_back(Store);
548  Offset += 4;
549  }
550  } else {
551  llvm_unreachable("Too many var args parameters.");
552  }
553  }
554 
555  // 2. Chain CopyFromReg nodes into a TokenFactor.
556  if (!CFRegNode.empty())
557  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, CFRegNode);
558 
559  // 3. Memcpy 'byVal' args & push final InVals.
560  // Aggregates passed "byVal" need to be copied by the callee.
561  // The callee will use a pointer to this copy, rather than the original
562  // pointer.
563  for (const auto &ArgDI : ArgData) {
564  if (ArgDI.Flags.isByVal() && ArgDI.Flags.getByValSize()) {
565  unsigned Size = ArgDI.Flags.getByValSize();
566  unsigned Align = std::max(StackSlotSize, ArgDI.Flags.getByValAlign());
567  // Create a new object on the stack and copy the pointee into it.
568  int FI = MFI.CreateStackObject(Size, Align, false);
569  SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
570  InVals.push_back(FIN);
571  MemOps.push_back(DAG.getMemcpy(
572  Chain, dl, FIN, ArgDI.SDV, DAG.getConstant(Size, dl, MVT::i32), Align,
573  false, false, false, MachinePointerInfo(), MachinePointerInfo()));
574  } else {
575  InVals.push_back(ArgDI.SDV);
576  }
577  }
578 
579  // 4. Chain mem ops nodes into a TokenFactor.
580  if (!MemOps.empty()) {
581  MemOps.push_back(Chain);
582  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps);
583  }
584 
585  return Chain;
586 }
587 
588 //===----------------------------------------------------------------------===//
589 // Return Value Calling Convention Implementation
590 //===----------------------------------------------------------------------===//
591 
592 bool ARCTargetLowering::CanLowerReturn(
593  CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
596  CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
597  if (!CCInfo.CheckReturn(Outs, RetCC_ARC))
598  return false;
599  if (CCInfo.getNextStackOffset() != 0 && IsVarArg)
600  return false;
601  return true;
602 }
603 
604 SDValue
605 ARCTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
606  bool IsVarArg,
608  const SmallVectorImpl<SDValue> &OutVals,
609  const SDLoc &dl, SelectionDAG &DAG) const {
610  auto *AFI = DAG.getMachineFunction().getInfo<ARCFunctionInfo>();
612 
613  // CCValAssign - represent the assignment of
614  // the return value to a location
616 
617  // CCState - Info about the registers and stack slot.
618  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
619  *DAG.getContext());
620 
621  // Analyze return values.
622  if (!IsVarArg)
623  CCInfo.AllocateStack(AFI->getReturnStackOffset(), 4);
624 
625  CCInfo.AnalyzeReturn(Outs, RetCC_ARC);
626 
627  SDValue Flag;
628  SmallVector<SDValue, 4> RetOps(1, Chain);
629  SmallVector<SDValue, 4> MemOpChains;
630  // Handle return values that must be copied to memory.
631  for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
632  CCValAssign &VA = RVLocs[i];
633  if (VA.isRegLoc())
634  continue;
635  assert(VA.isMemLoc());
636  if (IsVarArg) {
637  report_fatal_error("Can't return value from vararg function in memory");
638  }
639 
640  int Offset = VA.getLocMemOffset();
641  unsigned ObjSize = VA.getLocVT().getStoreSize();
642  // Create the frame index object for the memory location.
643  int FI = MFI.CreateFixedObject(ObjSize, Offset, false);
644 
645  // Create a SelectionDAG node corresponding to a store
646  // to this memory location.
647  SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
648  MemOpChains.push_back(DAG.getStore(
649  Chain, dl, OutVals[i], FIN,
651  }
652 
653  // Transform all store nodes into one single node because
654  // all stores are independent of each other.
655  if (!MemOpChains.empty())
656  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
657 
658  // Now handle return values copied to registers.
659  for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
660  CCValAssign &VA = RVLocs[i];
661  if (!VA.isRegLoc())
662  continue;
663  // Copy the result values into the output registers.
664  Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Flag);
665 
666  // guarantee that all emitted copies are
667  // stuck together, avoiding something bad
668  Flag = Chain.getValue(1);
669  RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
670  }
671 
672  RetOps[0] = Chain; // Update chain.
673 
674  // Add the flag if we have it.
675  if (Flag.getNode())
676  RetOps.push_back(Flag);
677 
678  // What to do with the RetOps?
679  return DAG.getNode(ARCISD::RET, dl, MVT::Other, RetOps);
680 }
681 
682 //===----------------------------------------------------------------------===//
683 // Target Optimization Hooks
684 //===----------------------------------------------------------------------===//
685 
686 SDValue ARCTargetLowering::PerformDAGCombine(SDNode *N,
687  DAGCombinerInfo &DCI) const {
688  return {};
689 }
690 
691 //===----------------------------------------------------------------------===//
692 // Addressing mode description hooks
693 //===----------------------------------------------------------------------===//
694 
695 /// Return true if the addressing mode represented by AM is legal for this
696 /// target, for a load/store of the specified type.
698  const AddrMode &AM, Type *Ty,
699  unsigned AS,
700  Instruction *I) const {
701  return AM.Scale == 0;
702 }
703 
704 // Don't emit tail calls for the time being.
705 bool ARCTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
706  return false;
707 }
708 
709 SDValue ARCTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
710  const ARCRegisterInfo &ARI = *Subtarget.getRegisterInfo();
712  MachineFrameInfo &MFI = MF.getFrameInfo();
713  MFI.setFrameAddressIsTaken(true);
714 
715  EVT VT = Op.getValueType();
716  SDLoc dl(Op);
717  assert(cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0 &&
718  "Only support lowering frame addr of current frame.");
719  unsigned FrameReg = ARI.getFrameRegister(MF);
720  return DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
721 }
722 
723 SDValue ARCTargetLowering::LowerGlobalAddress(SDValue Op,
724  SelectionDAG &DAG) const {
725  const GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op);
726  const GlobalValue *GV = GN->getGlobal();
727  SDLoc dl(GN);
728  int64_t Offset = GN->getOffset();
729  SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, Offset);
730  return DAG.getNode(ARCISD::GAWRAPPER, dl, MVT::i32, GA);
731 }
732 
735  auto *FuncInfo = MF.getInfo<ARCFunctionInfo>();
736 
737  // vastart just stores the address of the VarArgsFrameIndex slot into the
738  // memory location argument.
739  SDLoc dl(Op);
741  SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
742  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
743  return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1),
744  MachinePointerInfo(SV));
745 }
746 
748  switch (Op.getOpcode()) {
749  case ISD::GlobalAddress:
750  return LowerGlobalAddress(Op, DAG);
751  case ISD::FRAMEADDR:
752  return LowerFRAMEADDR(Op, DAG);
753  case ISD::SELECT_CC:
754  return LowerSELECT_CC(Op, DAG);
755  case ISD::BR_CC:
756  return LowerBR_CC(Op, DAG);
758  return LowerSIGN_EXTEND_INREG(Op, DAG);
759  case ISD::JumpTable:
760  return LowerJumpTable(Op, DAG);
761  case ISD::VASTART:
762  return LowerVASTART(Op, DAG);
763  default:
764  llvm_unreachable("unimplemented operand");
765  }
766 }
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:913
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:110
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.
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:852
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:139
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:678
This class represents lattice values for constants.
Definition: AllocatorList.h:23
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:730
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:252
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:408
#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.
C - The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
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:459
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:434
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:41
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:463
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:403
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:72
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:726
const ARCRegisterInfo * getRegisterInfo() const override
Definition: ARCSubtarget.h:55
unsigned getNextStackOffset() const
getNextStackOffset - Return the next stack offset such that all stack slots satisfy their alignment r...
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:400
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:200
SmallVector< ISD::OutputArg, 32 > Outs
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
Definition: ISDOpcodes.h:995
UNDEF - An undefined node.
Definition: ISDOpcodes.h:177
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:117
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...
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:45
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:64
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:759
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:840
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...
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:750
virtual 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...
Extended Value Type.
Definition: ValueTypes.h:33
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:52
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:639
TokenFactor - This node takes multiple tokens as input and produces a single token result...
Definition: ISDOpcodes.h:49
const TargetLowering & getTargetLoweringInfo() const
Definition: SelectionDAG.h:406
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:221
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
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:1050
BRCOND - Conditional branch.
Definition: ISDOpcodes.h:672
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
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:685
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...
Fast - This calling convention attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:42
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)
amdgpu Simplify well known AMD library false FunctionCallee Callee
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:492
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:495
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:666
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:755
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:411
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:711
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
unsigned getLocMemOffset() const
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:55
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:510
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:642
#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:46
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:72
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:80
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:65
Conversion operators.
Definition: ISDOpcodes.h:489
const SDValue & getOperand(unsigned i) const
unsigned getLocReg() const
#define LLVM_DEBUG(X)
Definition: Debug.h:122
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
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:410
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:628
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:404