LLVM  9.0.0svn
ARMCallLowering.cpp
Go to the documentation of this file.
1 //===- llvm/lib/Target/ARM/ARMCallLowering.cpp - Call lowering ------------===//
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 /// \file
10 /// This file implements the lowering of LLVM calls to machine code calls for
11 /// GlobalISel.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "ARMCallLowering.h"
16 #include "ARMBaseInstrInfo.h"
17 #include "ARMISelLowering.h"
18 #include "ARMSubtarget.h"
19 #include "Utils/ARMBaseInfo.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/CodeGen/Analysis.h"
36 #include "llvm/IR/Attributes.h"
37 #include "llvm/IR/DataLayout.h"
38 #include "llvm/IR/DerivedTypes.h"
39 #include "llvm/IR/Function.h"
40 #include "llvm/IR/Type.h"
41 #include "llvm/IR/Value.h"
42 #include "llvm/Support/Casting.h"
45 #include <algorithm>
46 #include <cassert>
47 #include <cstdint>
48 #include <utility>
49 
50 using namespace llvm;
51 
53  : CallLowering(&TLI) {}
54 
55 static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI,
56  Type *T) {
57  if (T->isArrayTy())
58  return true;
59 
60  if (T->isStructTy()) {
61  // For now we only allow homogeneous structs that we can manipulate with
62  // G_MERGE_VALUES and G_UNMERGE_VALUES
63  auto StructT = cast<StructType>(T);
64  for (unsigned i = 1, e = StructT->getNumElements(); i != e; ++i)
65  if (StructT->getElementType(i) != StructT->getElementType(0))
66  return false;
67  return true;
68  }
69 
70  EVT VT = TLI.getValueType(DL, T, true);
71  if (!VT.isSimple() || VT.isVector() ||
72  !(VT.isInteger() || VT.isFloatingPoint()))
73  return false;
74 
75  unsigned VTSize = VT.getSimpleVT().getSizeInBits();
76 
77  if (VTSize == 64)
78  // FIXME: Support i64 too
79  return VT.isFloatingPoint();
80 
81  return VTSize == 1 || VTSize == 8 || VTSize == 16 || VTSize == 32;
82 }
83 
84 namespace {
85 
86 /// Helper class for values going out through an ABI boundary (used for handling
87 /// function return values and call parameters).
88 struct OutgoingValueHandler : public CallLowering::ValueHandler {
89  OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
90  MachineInstrBuilder &MIB, CCAssignFn *AssignFn)
91  : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
92 
93  unsigned getStackAddress(uint64_t Size, int64_t Offset,
94  MachinePointerInfo &MPO) override {
95  assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
96  "Unsupported size");
97 
98  LLT p0 = LLT::pointer(0, 32);
99  LLT s32 = LLT::scalar(32);
100  unsigned SPReg = MRI.createGenericVirtualRegister(p0);
101  MIRBuilder.buildCopy(SPReg, ARM::SP);
102 
103  unsigned OffsetReg = MRI.createGenericVirtualRegister(s32);
104  MIRBuilder.buildConstant(OffsetReg, Offset);
105 
106  unsigned AddrReg = MRI.createGenericVirtualRegister(p0);
107  MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
108 
109  MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
110  return AddrReg;
111  }
112 
113  void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
114  CCValAssign &VA) override {
115  assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
116  assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
117 
118  assert(VA.getValVT().getSizeInBits() <= 64 && "Unsupported value size");
119  assert(VA.getLocVT().getSizeInBits() <= 64 && "Unsupported location size");
120 
121  unsigned ExtReg = extendRegister(ValVReg, VA);
122  MIRBuilder.buildCopy(PhysReg, ExtReg);
123  MIB.addUse(PhysReg, RegState::Implicit);
124  }
125 
126  void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
127  MachinePointerInfo &MPO, CCValAssign &VA) override {
128  assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
129  "Unsupported size");
130 
131  unsigned ExtReg = extendRegister(ValVReg, VA);
132  auto MMO = MIRBuilder.getMF().getMachineMemOperand(
134  /* Alignment */ 1);
135  MIRBuilder.buildStore(ExtReg, Addr, *MMO);
136  }
137 
138  unsigned assignCustomValue(const CallLowering::ArgInfo &Arg,
139  ArrayRef<CCValAssign> VAs) override {
140  CCValAssign VA = VAs[0];
141  assert(VA.needsCustom() && "Value doesn't need custom handling");
142  assert(VA.getValVT() == MVT::f64 && "Unsupported type");
143 
144  CCValAssign NextVA = VAs[1];
145  assert(NextVA.needsCustom() && "Value doesn't need custom handling");
146  assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
147 
148  assert(VA.getValNo() == NextVA.getValNo() &&
149  "Values belong to different arguments");
150 
151  assert(VA.isRegLoc() && "Value should be in reg");
152  assert(NextVA.isRegLoc() && "Value should be in reg");
153 
154  unsigned NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
156  MIRBuilder.buildUnmerge(NewRegs, Arg.Reg);
157 
158  bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
159  if (!IsLittle)
160  std::swap(NewRegs[0], NewRegs[1]);
161 
162  assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
163  assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
164 
165  return 1;
166  }
167 
168  bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
169  CCValAssign::LocInfo LocInfo,
170  const CallLowering::ArgInfo &Info, CCState &State) override {
171  if (AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State))
172  return true;
173 
174  StackSize =
175  std::max(StackSize, static_cast<uint64_t>(State.getNextStackOffset()));
176  return false;
177  }
178 
179  MachineInstrBuilder &MIB;
180  uint64_t StackSize = 0;
181 };
182 
183 } // end anonymous namespace
184 
185 void ARMCallLowering::splitToValueTypes(
186  const ArgInfo &OrigArg, SmallVectorImpl<ArgInfo> &SplitArgs,
187  MachineFunction &MF, const SplitArgTy &PerformArgSplit) const {
188  const ARMTargetLowering &TLI = *getTLI<ARMTargetLowering>();
189  LLVMContext &Ctx = OrigArg.Ty->getContext();
190  const DataLayout &DL = MF.getDataLayout();
192  const Function &F = MF.getFunction();
193 
194  SmallVector<EVT, 4> SplitVTs;
196  ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
197 
198  if (SplitVTs.size() == 1) {
199  // Even if there is no splitting to do, we still want to replace the
200  // original type (e.g. pointer type -> integer).
201  auto Flags = OrigArg.Flags;
202  unsigned OriginalAlignment = DL.getABITypeAlignment(OrigArg.Ty);
203  Flags.setOrigAlign(OriginalAlignment);
204  SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx), Flags,
205  OrigArg.IsFixed);
206  return;
207  }
208 
209  unsigned FirstRegIdx = SplitArgs.size();
210  for (unsigned i = 0, e = SplitVTs.size(); i != e; ++i) {
211  EVT SplitVT = SplitVTs[i];
212  Type *SplitTy = SplitVT.getTypeForEVT(Ctx);
213  auto Flags = OrigArg.Flags;
214 
215  unsigned OriginalAlignment = DL.getABITypeAlignment(SplitTy);
216  Flags.setOrigAlign(OriginalAlignment);
217 
218  bool NeedsConsecutiveRegisters =
220  SplitTy, F.getCallingConv(), F.isVarArg());
221  if (NeedsConsecutiveRegisters) {
222  Flags.setInConsecutiveRegs();
223  if (i == e - 1)
224  Flags.setInConsecutiveRegsLast();
225  }
226 
227  SplitArgs.push_back(
228  ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*SplitTy, DL)),
229  SplitTy, Flags, OrigArg.IsFixed});
230  }
231 
232  for (unsigned i = 0; i < Offsets.size(); ++i)
233  PerformArgSplit(SplitArgs[FirstRegIdx + i].Reg, Offsets[i] * 8);
234 }
235 
236 /// Lower the return value for the already existing \p Ret. This assumes that
237 /// \p MIRBuilder's insertion point is correct.
238 bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
239  const Value *Val, ArrayRef<unsigned> VRegs,
240  MachineInstrBuilder &Ret) const {
241  if (!Val)
242  // Nothing to do here.
243  return true;
244 
245  auto &MF = MIRBuilder.getMF();
246  const auto &F = MF.getFunction();
247 
248  auto DL = MF.getDataLayout();
249  auto &TLI = *getTLI<ARMTargetLowering>();
250  if (!isSupportedType(DL, TLI, Val->getType()))
251  return false;
252 
253  SmallVector<EVT, 4> SplitEVTs;
254  ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs);
255  assert(VRegs.size() == SplitEVTs.size() &&
256  "For each split Type there should be exactly one VReg.");
257 
258  SmallVector<ArgInfo, 4> SplitVTs;
259  LLVMContext &Ctx = Val->getType()->getContext();
260  for (unsigned i = 0; i < SplitEVTs.size(); ++i) {
261  ArgInfo CurArgInfo(VRegs[i], SplitEVTs[i].getTypeForEVT(Ctx));
262  setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
263 
265  splitToValueTypes(
266  CurArgInfo, SplitVTs, MF,
267  [&](unsigned Reg, uint64_t Offset) { Regs.push_back(Reg); });
268  if (Regs.size() > 1)
269  MIRBuilder.buildUnmerge(Regs, VRegs[i]);
270  }
271 
272  CCAssignFn *AssignFn =
273  TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
274 
275  OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret, AssignFn);
276  return handleAssignments(MIRBuilder, SplitVTs, RetHandler);
277 }
278 
280  const Value *Val,
281  ArrayRef<unsigned> VRegs) const {
282  assert(!Val == VRegs.empty() && "Return value without a vreg");
283 
284  auto const &ST = MIRBuilder.getMF().getSubtarget<ARMSubtarget>();
285  unsigned Opcode = ST.getReturnOpcode();
286  auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL));
287 
288  if (!lowerReturnVal(MIRBuilder, Val, VRegs, Ret))
289  return false;
290 
291  MIRBuilder.insertInstr(Ret);
292  return true;
293 }
294 
295 namespace {
296 
297 /// Helper class for values coming in through an ABI boundary (used for handling
298 /// formal arguments and call return values).
299 struct IncomingValueHandler : public CallLowering::ValueHandler {
300  IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
301  CCAssignFn AssignFn)
302  : ValueHandler(MIRBuilder, MRI, AssignFn) {}
303 
304  unsigned getStackAddress(uint64_t Size, int64_t Offset,
305  MachinePointerInfo &MPO) override {
306  assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
307  "Unsupported size");
308 
309  auto &MFI = MIRBuilder.getMF().getFrameInfo();
310 
311  int FI = MFI.CreateFixedObject(Size, Offset, true);
312  MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
313 
314  unsigned AddrReg =
316  MIRBuilder.buildFrameIndex(AddrReg, FI);
317 
318  return AddrReg;
319  }
320 
321  void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
322  MachinePointerInfo &MPO, CCValAssign &VA) override {
323  assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
324  "Unsupported size");
325 
326  if (VA.getLocInfo() == CCValAssign::SExt ||
327  VA.getLocInfo() == CCValAssign::ZExt) {
328  // If the value is zero- or sign-extended, its size becomes 4 bytes, so
329  // that's what we should load.
330  Size = 4;
331  assert(MRI.getType(ValVReg).isScalar() && "Only scalars supported atm");
332 
333  auto LoadVReg = MRI.createGenericVirtualRegister(LLT::scalar(32));
334  buildLoad(LoadVReg, Addr, Size, /* Alignment */ 1, MPO);
335  MIRBuilder.buildTrunc(ValVReg, LoadVReg);
336  } else {
337  // If the value is not extended, a simple load will suffice.
338  buildLoad(ValVReg, Addr, Size, /* Alignment */ 1, MPO);
339  }
340  }
341 
342  void buildLoad(unsigned Val, unsigned Addr, uint64_t Size, unsigned Alignment,
343  MachinePointerInfo &MPO) {
344  auto MMO = MIRBuilder.getMF().getMachineMemOperand(
345  MPO, MachineMemOperand::MOLoad, Size, Alignment);
346  MIRBuilder.buildLoad(Val, Addr, *MMO);
347  }
348 
349  void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
350  CCValAssign &VA) override {
351  assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
352  assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
353 
354  auto ValSize = VA.getValVT().getSizeInBits();
355  auto LocSize = VA.getLocVT().getSizeInBits();
356 
357  assert(ValSize <= 64 && "Unsupported value size");
358  assert(LocSize <= 64 && "Unsupported location size");
359 
360  markPhysRegUsed(PhysReg);
361  if (ValSize == LocSize) {
362  MIRBuilder.buildCopy(ValVReg, PhysReg);
363  } else {
364  assert(ValSize < LocSize && "Extensions not supported");
365 
366  // We cannot create a truncating copy, nor a trunc of a physical register.
367  // Therefore, we need to copy the content of the physical register into a
368  // virtual one and then truncate that.
369  auto PhysRegToVReg =
371  MIRBuilder.buildCopy(PhysRegToVReg, PhysReg);
372  MIRBuilder.buildTrunc(ValVReg, PhysRegToVReg);
373  }
374  }
375 
376  unsigned assignCustomValue(const ARMCallLowering::ArgInfo &Arg,
377  ArrayRef<CCValAssign> VAs) override {
378  CCValAssign VA = VAs[0];
379  assert(VA.needsCustom() && "Value doesn't need custom handling");
380  assert(VA.getValVT() == MVT::f64 && "Unsupported type");
381 
382  CCValAssign NextVA = VAs[1];
383  assert(NextVA.needsCustom() && "Value doesn't need custom handling");
384  assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
385 
386  assert(VA.getValNo() == NextVA.getValNo() &&
387  "Values belong to different arguments");
388 
389  assert(VA.isRegLoc() && "Value should be in reg");
390  assert(NextVA.isRegLoc() && "Value should be in reg");
391 
392  unsigned NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
394 
395  assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
396  assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
397 
398  bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
399  if (!IsLittle)
400  std::swap(NewRegs[0], NewRegs[1]);
401 
402  MIRBuilder.buildMerge(Arg.Reg, NewRegs);
403 
404  return 1;
405  }
406 
407  /// Marking a physical register as used is different between formal
408  /// parameters, where it's a basic block live-in, and call returns, where it's
409  /// an implicit-def of the call instruction.
410  virtual void markPhysRegUsed(unsigned PhysReg) = 0;
411 };
412 
413 struct FormalArgHandler : public IncomingValueHandler {
414  FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
415  CCAssignFn AssignFn)
416  : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
417 
418  void markPhysRegUsed(unsigned PhysReg) override {
419  MIRBuilder.getMBB().addLiveIn(PhysReg);
420  }
421 };
422 
423 } // end anonymous namespace
424 
426  const Function &F,
427  ArrayRef<unsigned> VRegs) const {
428  auto &TLI = *getTLI<ARMTargetLowering>();
429  auto Subtarget = TLI.getSubtarget();
430 
431  if (Subtarget->isThumb1Only())
432  return false;
433 
434  // Quick exit if there aren't any args
435  if (F.arg_empty())
436  return true;
437 
438  if (F.isVarArg())
439  return false;
440 
441  auto &MF = MIRBuilder.getMF();
442  auto &MBB = MIRBuilder.getMBB();
443  auto DL = MF.getDataLayout();
444 
445  for (auto &Arg : F.args()) {
446  if (!isSupportedType(DL, TLI, Arg.getType()))
447  return false;
448  if (Arg.hasByValOrInAllocaAttr())
449  return false;
450  }
451 
452  CCAssignFn *AssignFn =
453  TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
454 
455  FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo(),
456  AssignFn);
457 
458  SmallVector<ArgInfo, 8> ArgInfos;
459  SmallVector<unsigned, 4> SplitRegs;
460  unsigned Idx = 0;
461  for (auto &Arg : F.args()) {
462  ArgInfo AInfo(VRegs[Idx], Arg.getType());
463  setArgFlags(AInfo, Idx + AttributeList::FirstArgIndex, DL, F);
464 
465  SplitRegs.clear();
466 
467  splitToValueTypes(AInfo, ArgInfos, MF, [&](unsigned Reg, uint64_t Offset) {
468  SplitRegs.push_back(Reg);
469  });
470 
471  if (!SplitRegs.empty())
472  MIRBuilder.buildMerge(VRegs[Idx], SplitRegs);
473 
474  Idx++;
475  }
476 
477  if (!MBB.empty())
478  MIRBuilder.setInstr(*MBB.begin());
479 
480  if (!handleAssignments(MIRBuilder, ArgInfos, ArgHandler))
481  return false;
482 
483  // Move back to the end of the basic block.
484  MIRBuilder.setMBB(MBB);
485  return true;
486 }
487 
488 namespace {
489 
490 struct CallReturnHandler : public IncomingValueHandler {
491  CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
492  MachineInstrBuilder MIB, CCAssignFn *AssignFn)
493  : IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
494 
495  void markPhysRegUsed(unsigned PhysReg) override {
496  MIB.addDef(PhysReg, RegState::Implicit);
497  }
498 
500 };
501 
502 // FIXME: This should move to the ARMSubtarget when it supports all the opcodes.
503 unsigned getCallOpcode(const ARMSubtarget &STI, bool isDirect) {
504  if (isDirect)
505  return STI.isThumb() ? ARM::tBL : ARM::BL;
506 
507  if (STI.isThumb())
508  return ARM::tBLXr;
509 
510  if (STI.hasV5TOps())
511  return ARM::BLX;
512 
513  if (STI.hasV4TOps())
514  return ARM::BX_CALL;
515 
516  return ARM::BMOVPCRX_CALL;
517 }
518 } // end anonymous namespace
519 
521  CallingConv::ID CallConv,
522  const MachineOperand &Callee,
523  const ArgInfo &OrigRet,
524  ArrayRef<ArgInfo> OrigArgs) const {
525  MachineFunction &MF = MIRBuilder.getMF();
526  const auto &TLI = *getTLI<ARMTargetLowering>();
527  const auto &DL = MF.getDataLayout();
528  const auto &STI = MF.getSubtarget<ARMSubtarget>();
529  const TargetRegisterInfo *TRI = STI.getRegisterInfo();
531 
532  if (STI.genLongCalls())
533  return false;
534 
535  if (STI.isThumb1Only())
536  return false;
537 
538  auto CallSeqStart = MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN);
539 
540  // Create the call instruction so we can add the implicit uses of arg
541  // registers, but don't insert it yet.
542  bool IsDirect = !Callee.isReg();
543  auto CallOpcode = getCallOpcode(STI, IsDirect);
544  auto MIB = MIRBuilder.buildInstrNoInsert(CallOpcode);
545 
546  bool IsThumb = STI.isThumb();
547  if (IsThumb)
548  MIB.add(predOps(ARMCC::AL));
549 
550  MIB.add(Callee);
551  if (!IsDirect) {
552  auto CalleeReg = Callee.getReg();
553  if (CalleeReg && !TRI->isPhysicalRegister(CalleeReg)) {
554  unsigned CalleeIdx = IsThumb ? 2 : 0;
555  MIB->getOperand(CalleeIdx).setReg(constrainOperandRegClass(
556  MF, *TRI, MRI, *STI.getInstrInfo(), *STI.getRegBankInfo(),
557  *MIB.getInstr(), MIB->getDesc(), Callee, CalleeIdx));
558  }
559  }
560 
561  MIB.addRegMask(TRI->getCallPreservedMask(MF, CallConv));
562 
563  bool IsVarArg = false;
564  SmallVector<ArgInfo, 8> ArgInfos;
565  for (auto Arg : OrigArgs) {
566  if (!isSupportedType(DL, TLI, Arg.Ty))
567  return false;
568 
569  if (!Arg.IsFixed)
570  IsVarArg = true;
571 
572  if (Arg.Flags.isByVal())
573  return false;
574 
576  splitToValueTypes(Arg, ArgInfos, MF, [&](unsigned Reg, uint64_t Offset) {
577  Regs.push_back(Reg);
578  });
579 
580  if (Regs.size() > 1)
581  MIRBuilder.buildUnmerge(Regs, Arg.Reg);
582  }
583 
584  auto ArgAssignFn = TLI.CCAssignFnForCall(CallConv, IsVarArg);
585  OutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB, ArgAssignFn);
586  if (!handleAssignments(MIRBuilder, ArgInfos, ArgHandler))
587  return false;
588 
589  // Now we can add the actual call instruction to the correct basic block.
590  MIRBuilder.insertInstr(MIB);
591 
592  if (!OrigRet.Ty->isVoidTy()) {
593  if (!isSupportedType(DL, TLI, OrigRet.Ty))
594  return false;
595 
596  ArgInfos.clear();
597  SmallVector<unsigned, 8> SplitRegs;
598  splitToValueTypes(OrigRet, ArgInfos, MF,
599  [&](unsigned Reg, uint64_t Offset) {
600  SplitRegs.push_back(Reg);
601  });
602 
603  auto RetAssignFn = TLI.CCAssignFnForReturn(CallConv, IsVarArg);
604  CallReturnHandler RetHandler(MIRBuilder, MRI, MIB, RetAssignFn);
605  if (!handleAssignments(MIRBuilder, ArgInfos, RetHandler))
606  return false;
607 
608  if (!SplitRegs.empty()) {
609  // We have split the value and allocated each individual piece, now build
610  // it up again.
611  MIRBuilder.buildMerge(OrigRet.Reg, SplitRegs);
612  }
613  }
614 
615  // We now know the size of the stack - update the ADJCALLSTACKDOWN
616  // accordingly.
617  CallSeqStart.addImm(ArgHandler.StackSize).addImm(0).add(predOps(ARMCC::AL));
618 
619  MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP)
620  .addImm(ArgHandler.StackSize)
621  .addImm(0)
622  .add(predOps(ARMCC::AL));
623 
624  return true;
625 }
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:176
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
const MachineInstrBuilder & add(const MachineOperand &MO) const
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:110
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:645
static LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
MachineInstrBuilder buildUnmerge(ArrayRef< LLT > Res, const SrcOp &Op)
Build and insert Res0, ...
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
MachineInstrBuilder buildGEP(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res = G_GEP Op0, Op1.
bool isThumb() const
Definition: ARMSubtarget.h:717
This class represents lattice values for constants.
Definition: AllocatorList.h:23
bool hasV4TOps() const
Definition: ARMSubtarget.h:538
bool isScalar() const
unsigned getReg() const
getReg - Returns the register number.
unsigned Reg
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:252
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change...
Offsets
Offsets in bytes from the start of the input buffer.
Definition: SIInstrInfo.h:1026
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
unsigned getValNo() const
unsigned const TargetRegisterInfo * TRI
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition: ValueTypes.h:140
F(f)
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition: Type.h:129
bool needsCustom() const
unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition: ValueTypes.h:135
MachineInstrBuilder buildStore(unsigned Val, unsigned Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
bool handleAssignments(MachineIRBuilder &MIRBuilder, ArrayRef< ArgInfo > Args, ValueHandler &Handler) const
Invoke Handler::assignArg on each of the given Args and then use Callback to move them to the assigne...
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
Definition: ValueTypes.cpp:205
ARMCallLowering(const ARMTargetLowering &TLI)
const MachineInstrBuilder & addUse(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:41
This file contains the simple types necessary to represent the attributes associated with functions a...
unsigned getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
LocInfo getLocInfo() const
unsigned getSizeInBits() const
unsigned getNextStackOffset() const
getNextStackOffset - Return the next stack offset such that all stack slots satisfy their alignment r...
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:244
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
bool arg_empty() const
Definition: Function.h:698
#define T
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don&#39;t insert <empty> = Opcode <empty>.
MachineFunction & getMF()
Getter for the function we currently build.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< uint64_t > *Offsets=nullptr, uint64_t StartingOffset=0)
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
Definition: Analysis.cpp:83
Analysis containing CSE Info
Definition: CSEInfo.cpp:20
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef< unsigned > VRegs) const override
This hook must be implemented to lower the incoming (formal) arguments, described by Args...
bool isVoidTy() const
Return true if this is &#39;void&#39;.
Definition: Type.h:140
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
unsigned const MachineRegisterInfo * MRI
Machine Value Type.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:148
Helper class to build MachineInstr.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op, unsigned Subreg=0)
Build and insert Res = COPY Op.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const FuncInfoTy &FuncInfo) const
Extended Value Type.
Definition: ValueTypes.h:33
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_TRUNC Op.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
size_t size() const
Definition: SmallVector.h:52
Argument handling is mostly uniform between the four places that make these decisions: function forma...
Definition: CallLowering.h:61
This class contains a discriminated union of information about pointers in memory operands...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
MachineInstrBuilder buildFrameIndex(unsigned Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
The memory access writes data.
unsigned createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
MachineInstrBuilder buildMerge(const DstOp &Res, ArrayRef< unsigned > Ops)
Build and insert Res = G_MERGE_VALUES Op0, ...
CCState - This class holds information needed while lowering arguments and return values...
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:212
MachineOperand class - Representation of each machine instruction operand.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:841
CCValAssign - Represent assignment of one arg/retval to a location.
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
Definition: DataLayout.cpp:749
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, ArrayRef< unsigned > VRegs) const override
This hook must be implemented to lower outgoing return values, described by Val, into the specified v...
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
This file declares the MachineIRBuilder class.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:940
unsigned getReturnOpcode() const
Returns the correct return opcode for the current feature set.
Definition: ARMSubtarget.h:809
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
The memory access reads data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:150
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:55
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
uint32_t Size
Definition: Profile.cpp:46
static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI, Type *T)
bool hasV5TOps() const
Definition: ARMSubtarget.h:539
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegLoc() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool lowerCall(MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv, const MachineOperand &Callee, const ArgInfo &OrigRet, ArrayRef< ArgInfo > OrigArgs) const override
This hook must be implemented to lower the given call instruction, including argument and return valu...
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
LLVM Value Representation.
Definition: Value.h:72
MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
bool functionArgumentNeedsConsecutiveRegisters(Type *Ty, CallingConv::ID CallConv, bool isVarArg) const override
Returns true if an argument of type Ty needs to be passed in a contiguous block of registers in calli...
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
unsigned constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const MCInstrDesc &II, const MachineOperand &RegMO, unsigned OpIdx)
Try to constrain Reg so that it is usable by argument OpIdx of the provided MCInstrDesc II...
Definition: Utils.cpp:46
const MachineInstrBuilder & addDef(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
This file describes how to lower LLVM calls to machine code calls.
unsigned getLocReg() const
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition: ValueTypes.h:125
iterator_range< arg_iterator > args()
Definition: Function.h:688
bool isStructTy() const
True if this is an instance of StructType.
Definition: Type.h:217
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:143
bool isArrayTy() const
True if this is an instance of ArrayType.
Definition: Type.h:220