LLVM  12.0.0git
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 pseudo 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(), Align(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  Align Alignment =
567  std::max(Align(StackSlotSize), ArgDI.Flags.getNonZeroByValAlign());
568  // Create a new object on the stack and copy the pointee into it.
569  int FI = MFI.CreateStackObject(Size, Alignment, 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),
574  Alignment, false, false, false, MachinePointerInfo(),
575  MachinePointerInfo()));
576  } else {
577  InVals.push_back(ArgDI.SDV);
578  }
579  }
580 
581  // 4. Chain mem ops nodes into a TokenFactor.
582  if (!MemOps.empty()) {
583  MemOps.push_back(Chain);
584  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps);
585  }
586 
587  return Chain;
588 }
589 
590 //===----------------------------------------------------------------------===//
591 // Return Value Calling Convention Implementation
592 //===----------------------------------------------------------------------===//
593 
594 bool ARCTargetLowering::CanLowerReturn(
595  CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
598  CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
599  if (!CCInfo.CheckReturn(Outs, RetCC_ARC))
600  return false;
601  if (CCInfo.getNextStackOffset() != 0 && IsVarArg)
602  return false;
603  return true;
604 }
605 
606 SDValue
607 ARCTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
608  bool IsVarArg,
610  const SmallVectorImpl<SDValue> &OutVals,
611  const SDLoc &dl, SelectionDAG &DAG) const {
612  auto *AFI = DAG.getMachineFunction().getInfo<ARCFunctionInfo>();
614 
615  // CCValAssign - represent the assignment of
616  // the return value to a location
618 
619  // CCState - Info about the registers and stack slot.
620  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
621  *DAG.getContext());
622 
623  // Analyze return values.
624  if (!IsVarArg)
625  CCInfo.AllocateStack(AFI->getReturnStackOffset(), Align(4));
626 
627  CCInfo.AnalyzeReturn(Outs, RetCC_ARC);
628 
629  SDValue Flag;
630  SmallVector<SDValue, 4> RetOps(1, Chain);
631  SmallVector<SDValue, 4> MemOpChains;
632  // Handle return values that must be copied to memory.
633  for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
634  CCValAssign &VA = RVLocs[i];
635  if (VA.isRegLoc())
636  continue;
637  assert(VA.isMemLoc());
638  if (IsVarArg) {
639  report_fatal_error("Can't return value from vararg function in memory");
640  }
641 
642  int Offset = VA.getLocMemOffset();
643  unsigned ObjSize = VA.getLocVT().getStoreSize();
644  // Create the frame index object for the memory location.
645  int FI = MFI.CreateFixedObject(ObjSize, Offset, false);
646 
647  // Create a SelectionDAG node corresponding to a store
648  // to this memory location.
649  SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
650  MemOpChains.push_back(DAG.getStore(
651  Chain, dl, OutVals[i], FIN,
653  }
654 
655  // Transform all store nodes into one single node because
656  // all stores are independent of each other.
657  if (!MemOpChains.empty())
658  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
659 
660  // Now handle return values copied to registers.
661  for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
662  CCValAssign &VA = RVLocs[i];
663  if (!VA.isRegLoc())
664  continue;
665  // Copy the result values into the output registers.
666  Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Flag);
667 
668  // guarantee that all emitted copies are
669  // stuck together, avoiding something bad
670  Flag = Chain.getValue(1);
671  RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
672  }
673 
674  RetOps[0] = Chain; // Update chain.
675 
676  // Add the flag if we have it.
677  if (Flag.getNode())
678  RetOps.push_back(Flag);
679 
680  // What to do with the RetOps?
681  return DAG.getNode(ARCISD::RET, dl, MVT::Other, RetOps);
682 }
683 
684 //===----------------------------------------------------------------------===//
685 // Target Optimization Hooks
686 //===----------------------------------------------------------------------===//
687 
688 SDValue ARCTargetLowering::PerformDAGCombine(SDNode *N,
689  DAGCombinerInfo &DCI) const {
690  return {};
691 }
692 
693 //===----------------------------------------------------------------------===//
694 // Addressing mode description hooks
695 //===----------------------------------------------------------------------===//
696 
697 /// Return true if the addressing mode represented by AM is legal for this
698 /// target, for a load/store of the specified type.
700  const AddrMode &AM, Type *Ty,
701  unsigned AS,
702  Instruction *I) const {
703  return AM.Scale == 0;
704 }
705 
706 // Don't emit tail calls for the time being.
707 bool ARCTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
708  return false;
709 }
710 
711 SDValue ARCTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
712  const ARCRegisterInfo &ARI = *Subtarget.getRegisterInfo();
714  MachineFrameInfo &MFI = MF.getFrameInfo();
715  MFI.setFrameAddressIsTaken(true);
716 
717  EVT VT = Op.getValueType();
718  SDLoc dl(Op);
719  assert(cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0 &&
720  "Only support lowering frame addr of current frame.");
721  Register FrameReg = ARI.getFrameRegister(MF);
722  return DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
723 }
724 
725 SDValue ARCTargetLowering::LowerGlobalAddress(SDValue Op,
726  SelectionDAG &DAG) const {
727  const GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op);
728  const GlobalValue *GV = GN->getGlobal();
729  SDLoc dl(GN);
730  int64_t Offset = GN->getOffset();
731  SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, Offset);
732  return DAG.getNode(ARCISD::GAWRAPPER, dl, MVT::i32, GA);
733 }
734 
737  auto *FuncInfo = MF.getInfo<ARCFunctionInfo>();
738 
739  // vastart just stores the address of the VarArgsFrameIndex slot into the
740  // memory location argument.
741  SDLoc dl(Op);
743  SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
744  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
745  return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1),
746  MachinePointerInfo(SV));
747 }
748 
750  switch (Op.getOpcode()) {
751  case ISD::GlobalAddress:
752  return LowerGlobalAddress(Op, DAG);
753  case ISD::FRAMEADDR:
754  return LowerFRAMEADDR(Op, DAG);
755  case ISD::SELECT_CC:
756  return LowerSELECT_CC(Op, DAG);
757  case ISD::BR_CC:
758  return LowerBR_CC(Op, DAG);
760  return LowerSIGN_EXTEND_INREG(Op, DAG);
761  case ISD::JumpTable:
762  return LowerJumpTable(Op, DAG);
763  case ISD::VASTART:
764  return LowerVASTART(Op, DAG);
765  default:
766  llvm_unreachable("unimplemented operand");
767  }
768 }
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
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:1111
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...
const GlobalValue * getGlobal() const
#define R4(n)
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:910
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:854
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Register getLocReg() const
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
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:903
ARCTargetLowering(const TargetMachine &TM, const ARCSubtarget &Subtarget)
This class represents a function call, abstracting a target machine&#39;s calling convention.
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:260
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:545
#define R2(n)
SDNode * getNode() const
get the SDNode which holds the desired result
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.
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:612
bool isMemLoc() const
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
Shift and rotation operations.
Definition: ISDOpcodes.h:576
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:674
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:497
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:424
std::underlying_type_t< E > 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
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:87
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:899
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:421
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:223
SmallVector< ISD::OutputArg, 32 > Outs
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
Definition: ISDOpcodes.h:1204
UNDEF - An undefined node.
Definition: ISDOpcodes.h:195
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition: MCRegister.h:19
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:138
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...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
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:68
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:932
unsigned AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
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:898
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
Register getFrameRegister(const MachineFunction &MF) const override
constexpr double e
Definition: MathExtras.h:58
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
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment, 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...
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:923
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save and restore.
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:35
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.
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.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
TokenFactor - This node takes multiple tokens as input and produces a single token result...
Definition: ISDOpcodes.h:52
const TargetLowering & getTargetLoweringInfo() const
Definition: SelectionDAG.h:427
CCState - This class holds information needed while lowering arguments and return values...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:664
#define R6(n)
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:350
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:223
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:883
CCValAssign - Represent assignment of one arg/retval to a location.
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:1335
BRCOND - Conditional branch.
Definition: ISDOpcodes.h:848
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:718
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)
amdgpu Simplify well known AMD library false FunctionCallee Callee
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:647
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:650
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:842
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:928
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:551
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:744
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
unsigned getLocMemOffset() const
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:665
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:817
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo)
#define I(x, y, z)
Definition: MD5.cpp:59
#define N
uint32_t Size
Definition: Profile.cpp:46
unsigned getOpcode() const
SDValue getValue(unsigned R) const
C - The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
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)
int CreateStackObject(uint64_t Size, Align 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...
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
LLVM Value Representation.
Definition: Value.h:74
SDValue getRegister(unsigned Reg, EVT VT)
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:65
Conversion operators.
Definition: ISDOpcodes.h:644
const SDValue & getOperand(unsigned i) 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...
Fast - This calling convention attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:42
LLVMContext * getContext() const
Definition: SelectionDAG.h:431
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:540