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  bool isArgumentHandler() const override { return true; }
305 
306  unsigned getStackAddress(uint64_t Size, int64_t Offset,
307  MachinePointerInfo &MPO) override {
308  assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
309  "Unsupported size");
310 
311  auto &MFI = MIRBuilder.getMF().getFrameInfo();
312 
313  int FI = MFI.CreateFixedObject(Size, Offset, true);
314  MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
315 
316  unsigned AddrReg =
318  MIRBuilder.buildFrameIndex(AddrReg, FI);
319 
320  return AddrReg;
321  }
322 
323  void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
324  MachinePointerInfo &MPO, CCValAssign &VA) override {
325  assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
326  "Unsupported size");
327 
328  if (VA.getLocInfo() == CCValAssign::SExt ||
329  VA.getLocInfo() == CCValAssign::ZExt) {
330  // If the value is zero- or sign-extended, its size becomes 4 bytes, so
331  // that's what we should load.
332  Size = 4;
333  assert(MRI.getType(ValVReg).isScalar() && "Only scalars supported atm");
334 
335  auto LoadVReg = MRI.createGenericVirtualRegister(LLT::scalar(32));
336  buildLoad(LoadVReg, Addr, Size, /* Alignment */ 1, MPO);
337  MIRBuilder.buildTrunc(ValVReg, LoadVReg);
338  } else {
339  // If the value is not extended, a simple load will suffice.
340  buildLoad(ValVReg, Addr, Size, /* Alignment */ 1, MPO);
341  }
342  }
343 
344  void buildLoad(unsigned Val, unsigned Addr, uint64_t Size, unsigned Alignment,
345  MachinePointerInfo &MPO) {
346  auto MMO = MIRBuilder.getMF().getMachineMemOperand(
347  MPO, MachineMemOperand::MOLoad, Size, Alignment);
348  MIRBuilder.buildLoad(Val, Addr, *MMO);
349  }
350 
351  void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
352  CCValAssign &VA) override {
353  assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
354  assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
355 
356  auto ValSize = VA.getValVT().getSizeInBits();
357  auto LocSize = VA.getLocVT().getSizeInBits();
358 
359  assert(ValSize <= 64 && "Unsupported value size");
360  assert(LocSize <= 64 && "Unsupported location size");
361 
362  markPhysRegUsed(PhysReg);
363  if (ValSize == LocSize) {
364  MIRBuilder.buildCopy(ValVReg, PhysReg);
365  } else {
366  assert(ValSize < LocSize && "Extensions not supported");
367 
368  // We cannot create a truncating copy, nor a trunc of a physical register.
369  // Therefore, we need to copy the content of the physical register into a
370  // virtual one and then truncate that.
371  auto PhysRegToVReg =
373  MIRBuilder.buildCopy(PhysRegToVReg, PhysReg);
374  MIRBuilder.buildTrunc(ValVReg, PhysRegToVReg);
375  }
376  }
377 
378  unsigned assignCustomValue(const ARMCallLowering::ArgInfo &Arg,
379  ArrayRef<CCValAssign> VAs) override {
380  CCValAssign VA = VAs[0];
381  assert(VA.needsCustom() && "Value doesn't need custom handling");
382  assert(VA.getValVT() == MVT::f64 && "Unsupported type");
383 
384  CCValAssign NextVA = VAs[1];
385  assert(NextVA.needsCustom() && "Value doesn't need custom handling");
386  assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
387 
388  assert(VA.getValNo() == NextVA.getValNo() &&
389  "Values belong to different arguments");
390 
391  assert(VA.isRegLoc() && "Value should be in reg");
392  assert(NextVA.isRegLoc() && "Value should be in reg");
393 
394  unsigned NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
396 
397  assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
398  assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
399 
400  bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
401  if (!IsLittle)
402  std::swap(NewRegs[0], NewRegs[1]);
403 
404  MIRBuilder.buildMerge(Arg.Reg, NewRegs);
405 
406  return 1;
407  }
408 
409  /// Marking a physical register as used is different between formal
410  /// parameters, where it's a basic block live-in, and call returns, where it's
411  /// an implicit-def of the call instruction.
412  virtual void markPhysRegUsed(unsigned PhysReg) = 0;
413 };
414 
415 struct FormalArgHandler : public IncomingValueHandler {
416  FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
417  CCAssignFn AssignFn)
418  : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
419 
420  void markPhysRegUsed(unsigned PhysReg) override {
421  MIRBuilder.getMBB().addLiveIn(PhysReg);
422  }
423 };
424 
425 } // end anonymous namespace
426 
428  const Function &F,
429  ArrayRef<unsigned> VRegs) const {
430  auto &TLI = *getTLI<ARMTargetLowering>();
431  auto Subtarget = TLI.getSubtarget();
432 
433  if (Subtarget->isThumb1Only())
434  return false;
435 
436  // Quick exit if there aren't any args
437  if (F.arg_empty())
438  return true;
439 
440  if (F.isVarArg())
441  return false;
442 
443  auto &MF = MIRBuilder.getMF();
444  auto &MBB = MIRBuilder.getMBB();
445  auto DL = MF.getDataLayout();
446 
447  for (auto &Arg : F.args()) {
448  if (!isSupportedType(DL, TLI, Arg.getType()))
449  return false;
450  if (Arg.hasByValOrInAllocaAttr())
451  return false;
452  }
453 
454  CCAssignFn *AssignFn =
455  TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
456 
457  FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo(),
458  AssignFn);
459 
460  SmallVector<ArgInfo, 8> ArgInfos;
461  SmallVector<unsigned, 4> SplitRegs;
462  unsigned Idx = 0;
463  for (auto &Arg : F.args()) {
464  ArgInfo AInfo(VRegs[Idx], Arg.getType());
465  setArgFlags(AInfo, Idx + AttributeList::FirstArgIndex, DL, F);
466 
467  SplitRegs.clear();
468 
469  splitToValueTypes(AInfo, ArgInfos, MF, [&](unsigned Reg, uint64_t Offset) {
470  SplitRegs.push_back(Reg);
471  });
472 
473  if (!SplitRegs.empty())
474  MIRBuilder.buildMerge(VRegs[Idx], SplitRegs);
475 
476  Idx++;
477  }
478 
479  if (!MBB.empty())
480  MIRBuilder.setInstr(*MBB.begin());
481 
482  if (!handleAssignments(MIRBuilder, ArgInfos, ArgHandler))
483  return false;
484 
485  // Move back to the end of the basic block.
486  MIRBuilder.setMBB(MBB);
487  return true;
488 }
489 
490 namespace {
491 
492 struct CallReturnHandler : public IncomingValueHandler {
493  CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
494  MachineInstrBuilder MIB, CCAssignFn *AssignFn)
495  : IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
496 
497  void markPhysRegUsed(unsigned PhysReg) override {
498  MIB.addDef(PhysReg, RegState::Implicit);
499  }
500 
502 };
503 
504 // FIXME: This should move to the ARMSubtarget when it supports all the opcodes.
505 unsigned getCallOpcode(const ARMSubtarget &STI, bool isDirect) {
506  if (isDirect)
507  return STI.isThumb() ? ARM::tBL : ARM::BL;
508 
509  if (STI.isThumb())
510  return ARM::tBLXr;
511 
512  if (STI.hasV5TOps())
513  return ARM::BLX;
514 
515  if (STI.hasV4TOps())
516  return ARM::BX_CALL;
517 
518  return ARM::BMOVPCRX_CALL;
519 }
520 } // end anonymous namespace
521 
523  CallingConv::ID CallConv,
524  const MachineOperand &Callee,
525  const ArgInfo &OrigRet,
526  ArrayRef<ArgInfo> OrigArgs) const {
527  MachineFunction &MF = MIRBuilder.getMF();
528  const auto &TLI = *getTLI<ARMTargetLowering>();
529  const auto &DL = MF.getDataLayout();
530  const auto &STI = MF.getSubtarget<ARMSubtarget>();
531  const TargetRegisterInfo *TRI = STI.getRegisterInfo();
533 
534  if (STI.genLongCalls())
535  return false;
536 
537  if (STI.isThumb1Only())
538  return false;
539 
540  auto CallSeqStart = MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN);
541 
542  // Create the call instruction so we can add the implicit uses of arg
543  // registers, but don't insert it yet.
544  bool IsDirect = !Callee.isReg();
545  auto CallOpcode = getCallOpcode(STI, IsDirect);
546  auto MIB = MIRBuilder.buildInstrNoInsert(CallOpcode);
547 
548  bool IsThumb = STI.isThumb();
549  if (IsThumb)
550  MIB.add(predOps(ARMCC::AL));
551 
552  MIB.add(Callee);
553  if (!IsDirect) {
554  auto CalleeReg = Callee.getReg();
555  if (CalleeReg && !TRI->isPhysicalRegister(CalleeReg)) {
556  unsigned CalleeIdx = IsThumb ? 2 : 0;
557  MIB->getOperand(CalleeIdx).setReg(constrainOperandRegClass(
558  MF, *TRI, MRI, *STI.getInstrInfo(), *STI.getRegBankInfo(),
559  *MIB.getInstr(), MIB->getDesc(), Callee, CalleeIdx));
560  }
561  }
562 
563  MIB.addRegMask(TRI->getCallPreservedMask(MF, CallConv));
564 
565  bool IsVarArg = false;
566  SmallVector<ArgInfo, 8> ArgInfos;
567  for (auto Arg : OrigArgs) {
568  if (!isSupportedType(DL, TLI, Arg.Ty))
569  return false;
570 
571  if (!Arg.IsFixed)
572  IsVarArg = true;
573 
574  if (Arg.Flags.isByVal())
575  return false;
576 
578  splitToValueTypes(Arg, ArgInfos, MF, [&](unsigned Reg, uint64_t Offset) {
579  Regs.push_back(Reg);
580  });
581 
582  if (Regs.size() > 1)
583  MIRBuilder.buildUnmerge(Regs, Arg.Reg);
584  }
585 
586  auto ArgAssignFn = TLI.CCAssignFnForCall(CallConv, IsVarArg);
587  OutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB, ArgAssignFn);
588  if (!handleAssignments(MIRBuilder, ArgInfos, ArgHandler))
589  return false;
590 
591  // Now we can add the actual call instruction to the correct basic block.
592  MIRBuilder.insertInstr(MIB);
593 
594  if (!OrigRet.Ty->isVoidTy()) {
595  if (!isSupportedType(DL, TLI, OrigRet.Ty))
596  return false;
597 
598  ArgInfos.clear();
599  SmallVector<unsigned, 8> SplitRegs;
600  splitToValueTypes(OrigRet, ArgInfos, MF,
601  [&](unsigned Reg, uint64_t Offset) {
602  SplitRegs.push_back(Reg);
603  });
604 
605  auto RetAssignFn = TLI.CCAssignFnForReturn(CallConv, IsVarArg);
606  CallReturnHandler RetHandler(MIRBuilder, MRI, MIB, RetAssignFn);
607  if (!handleAssignments(MIRBuilder, ArgInfos, RetHandler))
608  return false;
609 
610  if (!SplitRegs.empty()) {
611  // We have split the value and allocated each individual piece, now build
612  // it up again.
613  MIRBuilder.buildMerge(OrigRet.Reg, SplitRegs);
614  }
615  }
616 
617  // We now know the size of the stack - update the ADJCALLSTACKDOWN
618  // accordingly.
619  CallSeqStart.addImm(ArgHandler.StackSize).addImm(0).add(predOps(ARMCC::AL));
620 
621  MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP)
622  .addImm(ArgHandler.StackSize)
623  .addImm(0)
624  .add(predOps(ARMCC::AL));
625 
626  return true;
627 }
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:1034
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:701
#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.
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 buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
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:64
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:691
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