LLVM  10.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 isSupportedType(DL, TLI, T->getArrayElementType());
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 isSupportedType(DL, TLI, StructT->getElementType(0));
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  bool isIncomingArgumentHandler() const override { return false; }
94 
95  Register getStackAddress(uint64_t Size, int64_t Offset,
96  MachinePointerInfo &MPO) override {
97  assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
98  "Unsupported size");
99 
100  LLT p0 = LLT::pointer(0, 32);
101  LLT s32 = LLT::scalar(32);
102  Register SPReg = MRI.createGenericVirtualRegister(p0);
103  MIRBuilder.buildCopy(SPReg, Register(ARM::SP));
104 
105  Register OffsetReg = MRI.createGenericVirtualRegister(s32);
106  MIRBuilder.buildConstant(OffsetReg, Offset);
107 
108  Register AddrReg = MRI.createGenericVirtualRegister(p0);
109  MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
110 
111  MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
112  return AddrReg;
113  }
114 
115  void assignValueToReg(Register ValVReg, Register PhysReg,
116  CCValAssign &VA) override {
117  assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
118  assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
119 
120  assert(VA.getValVT().getSizeInBits() <= 64 && "Unsupported value size");
121  assert(VA.getLocVT().getSizeInBits() <= 64 && "Unsupported location size");
122 
123  Register ExtReg = extendRegister(ValVReg, VA);
124  MIRBuilder.buildCopy(PhysReg, ExtReg);
125  MIB.addUse(PhysReg, RegState::Implicit);
126  }
127 
128  void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size,
129  MachinePointerInfo &MPO, CCValAssign &VA) override {
130  assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
131  "Unsupported size");
132 
133  Register ExtReg = extendRegister(ValVReg, VA);
134  auto MMO = MIRBuilder.getMF().getMachineMemOperand(
136  /* Alignment */ 1);
137  MIRBuilder.buildStore(ExtReg, Addr, *MMO);
138  }
139 
140  unsigned assignCustomValue(const CallLowering::ArgInfo &Arg,
141  ArrayRef<CCValAssign> VAs) override {
142  assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet");
143 
144  CCValAssign VA = VAs[0];
145  assert(VA.needsCustom() && "Value doesn't need custom handling");
146  assert(VA.getValVT() == MVT::f64 && "Unsupported type");
147 
148  CCValAssign NextVA = VAs[1];
149  assert(NextVA.needsCustom() && "Value doesn't need custom handling");
150  assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
151 
152  assert(VA.getValNo() == NextVA.getValNo() &&
153  "Values belong to different arguments");
154 
155  assert(VA.isRegLoc() && "Value should be in reg");
156  assert(NextVA.isRegLoc() && "Value should be in reg");
157 
158  Register NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
160  MIRBuilder.buildUnmerge(NewRegs, Arg.Regs[0]);
161 
162  bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
163  if (!IsLittle)
164  std::swap(NewRegs[0], NewRegs[1]);
165 
166  assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
167  assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
168 
169  return 1;
170  }
171 
172  bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
173  CCValAssign::LocInfo LocInfo,
175  CCState &State) override {
176  if (AssignFn(ValNo, ValVT, LocVT, LocInfo, Flags, State))
177  return true;
178 
179  StackSize =
180  std::max(StackSize, static_cast<uint64_t>(State.getNextStackOffset()));
181  return false;
182  }
183 
184  MachineInstrBuilder &MIB;
185  uint64_t StackSize = 0;
186 };
187 
188 } // end anonymous namespace
189 
190 void ARMCallLowering::splitToValueTypes(const ArgInfo &OrigArg,
191  SmallVectorImpl<ArgInfo> &SplitArgs,
192  MachineFunction &MF) const {
193  const ARMTargetLowering &TLI = *getTLI<ARMTargetLowering>();
194  LLVMContext &Ctx = OrigArg.Ty->getContext();
195  const DataLayout &DL = MF.getDataLayout();
196  const Function &F = MF.getFunction();
197 
198  SmallVector<EVT, 4> SplitVTs;
199  ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, nullptr, nullptr, 0);
200  assert(OrigArg.Regs.size() == SplitVTs.size() && "Regs / types mismatch");
201 
202  if (SplitVTs.size() == 1) {
203  // Even if there is no splitting to do, we still want to replace the
204  // original type (e.g. pointer type -> integer).
205  auto Flags = OrigArg.Flags[0];
206  Flags.setOrigAlign(Align(DL.getABITypeAlignment(OrigArg.Ty)));
207  SplitArgs.emplace_back(OrigArg.Regs[0], SplitVTs[0].getTypeForEVT(Ctx),
208  Flags, OrigArg.IsFixed);
209  return;
210  }
211 
212  // Create one ArgInfo for each virtual register.
213  for (unsigned i = 0, e = SplitVTs.size(); i != e; ++i) {
214  EVT SplitVT = SplitVTs[i];
215  Type *SplitTy = SplitVT.getTypeForEVT(Ctx);
216  auto Flags = OrigArg.Flags[0];
217 
218  Flags.setOrigAlign(Align(DL.getABITypeAlignment(SplitTy)));
219 
220  bool NeedsConsecutiveRegisters =
222  SplitTy, F.getCallingConv(), F.isVarArg());
223  if (NeedsConsecutiveRegisters) {
224  Flags.setInConsecutiveRegs();
225  if (i == e - 1)
226  Flags.setInConsecutiveRegsLast();
227  }
228 
229  // FIXME: We also want to split SplitTy further.
230  Register PartReg = OrigArg.Regs[i];
231  SplitArgs.emplace_back(PartReg, SplitTy, Flags, OrigArg.IsFixed);
232  }
233 }
234 
235 /// Lower the return value for the already existing \p Ret. This assumes that
236 /// \p MIRBuilder's insertion point is correct.
237 bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
238  const Value *Val, ArrayRef<Register> VRegs,
239  MachineInstrBuilder &Ret) const {
240  if (!Val)
241  // Nothing to do here.
242  return true;
243 
244  auto &MF = MIRBuilder.getMF();
245  const auto &F = MF.getFunction();
246 
247  auto DL = MF.getDataLayout();
248  auto &TLI = *getTLI<ARMTargetLowering>();
249  if (!isSupportedType(DL, TLI, Val->getType()))
250  return false;
251 
252  ArgInfo OrigRetInfo(VRegs, Val->getType());
253  setArgFlags(OrigRetInfo, AttributeList::ReturnIndex, DL, F);
254 
255  SmallVector<ArgInfo, 4> SplitRetInfos;
256  splitToValueTypes(OrigRetInfo, SplitRetInfos, MF);
257 
258  CCAssignFn *AssignFn =
259  TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
260 
261  OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret, AssignFn);
262  return handleAssignments(MIRBuilder, SplitRetInfos, RetHandler);
263 }
264 
266  const Value *Val,
267  ArrayRef<Register> VRegs) const {
268  assert(!Val == VRegs.empty() && "Return value without a vreg");
269 
270  auto const &ST = MIRBuilder.getMF().getSubtarget<ARMSubtarget>();
271  unsigned Opcode = ST.getReturnOpcode();
272  auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL));
273 
274  if (!lowerReturnVal(MIRBuilder, Val, VRegs, Ret))
275  return false;
276 
277  MIRBuilder.insertInstr(Ret);
278  return true;
279 }
280 
281 namespace {
282 
283 /// Helper class for values coming in through an ABI boundary (used for handling
284 /// formal arguments and call return values).
285 struct IncomingValueHandler : public CallLowering::ValueHandler {
286  IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
287  CCAssignFn AssignFn)
288  : ValueHandler(MIRBuilder, MRI, AssignFn) {}
289 
290  bool isIncomingArgumentHandler() const override { return true; }
291 
292  Register getStackAddress(uint64_t Size, int64_t Offset,
293  MachinePointerInfo &MPO) override {
294  assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
295  "Unsupported size");
296 
297  auto &MFI = MIRBuilder.getMF().getFrameInfo();
298 
299  int FI = MFI.CreateFixedObject(Size, Offset, true);
300  MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
301 
302  Register AddrReg =
304  MIRBuilder.buildFrameIndex(AddrReg, FI);
305 
306  return AddrReg;
307  }
308 
309  void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size,
310  MachinePointerInfo &MPO, CCValAssign &VA) override {
311  assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
312  "Unsupported size");
313 
314  if (VA.getLocInfo() == CCValAssign::SExt ||
315  VA.getLocInfo() == CCValAssign::ZExt) {
316  // If the value is zero- or sign-extended, its size becomes 4 bytes, so
317  // that's what we should load.
318  Size = 4;
319  assert(MRI.getType(ValVReg).isScalar() && "Only scalars supported atm");
320 
321  auto LoadVReg = MRI.createGenericVirtualRegister(LLT::scalar(32));
322  buildLoad(LoadVReg, Addr, Size, /* Alignment */ 1, MPO);
323  MIRBuilder.buildTrunc(ValVReg, LoadVReg);
324  } else {
325  // If the value is not extended, a simple load will suffice.
326  buildLoad(ValVReg, Addr, Size, /* Alignment */ 1, MPO);
327  }
328  }
329 
330  void buildLoad(Register Val, Register Addr, uint64_t Size, unsigned Alignment,
331  MachinePointerInfo &MPO) {
332  auto MMO = MIRBuilder.getMF().getMachineMemOperand(
333  MPO, MachineMemOperand::MOLoad, Size, Alignment);
334  MIRBuilder.buildLoad(Val, Addr, *MMO);
335  }
336 
337  void assignValueToReg(Register ValVReg, Register PhysReg,
338  CCValAssign &VA) override {
339  assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
340  assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
341 
342  auto ValSize = VA.getValVT().getSizeInBits();
343  auto LocSize = VA.getLocVT().getSizeInBits();
344 
345  assert(ValSize <= 64 && "Unsupported value size");
346  assert(LocSize <= 64 && "Unsupported location size");
347 
348  markPhysRegUsed(PhysReg);
349  if (ValSize == LocSize) {
350  MIRBuilder.buildCopy(ValVReg, PhysReg);
351  } else {
352  assert(ValSize < LocSize && "Extensions not supported");
353 
354  // We cannot create a truncating copy, nor a trunc of a physical register.
355  // Therefore, we need to copy the content of the physical register into a
356  // virtual one and then truncate that.
357  auto PhysRegToVReg =
359  MIRBuilder.buildCopy(PhysRegToVReg, PhysReg);
360  MIRBuilder.buildTrunc(ValVReg, PhysRegToVReg);
361  }
362  }
363 
364  unsigned assignCustomValue(const ARMCallLowering::ArgInfo &Arg,
365  ArrayRef<CCValAssign> VAs) override {
366  assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet");
367 
368  CCValAssign VA = VAs[0];
369  assert(VA.needsCustom() && "Value doesn't need custom handling");
370  assert(VA.getValVT() == MVT::f64 && "Unsupported type");
371 
372  CCValAssign NextVA = VAs[1];
373  assert(NextVA.needsCustom() && "Value doesn't need custom handling");
374  assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
375 
376  assert(VA.getValNo() == NextVA.getValNo() &&
377  "Values belong to different arguments");
378 
379  assert(VA.isRegLoc() && "Value should be in reg");
380  assert(NextVA.isRegLoc() && "Value should be in reg");
381 
382  Register NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
384 
385  assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
386  assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
387 
388  bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
389  if (!IsLittle)
390  std::swap(NewRegs[0], NewRegs[1]);
391 
392  MIRBuilder.buildMerge(Arg.Regs[0], NewRegs);
393 
394  return 1;
395  }
396 
397  /// Marking a physical register as used is different between formal
398  /// parameters, where it's a basic block live-in, and call returns, where it's
399  /// an implicit-def of the call instruction.
400  virtual void markPhysRegUsed(unsigned PhysReg) = 0;
401 };
402 
403 struct FormalArgHandler : public IncomingValueHandler {
404  FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
405  CCAssignFn AssignFn)
406  : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
407 
408  void markPhysRegUsed(unsigned PhysReg) override {
409  MIRBuilder.getMRI()->addLiveIn(PhysReg);
410  MIRBuilder.getMBB().addLiveIn(PhysReg);
411  }
412 };
413 
414 } // end anonymous namespace
415 
417  MachineIRBuilder &MIRBuilder, const Function &F,
418  ArrayRef<ArrayRef<Register>> VRegs) const {
419  auto &TLI = *getTLI<ARMTargetLowering>();
420  auto Subtarget = TLI.getSubtarget();
421 
422  if (Subtarget->isThumb1Only())
423  return false;
424 
425  // Quick exit if there aren't any args
426  if (F.arg_empty())
427  return true;
428 
429  if (F.isVarArg())
430  return false;
431 
432  auto &MF = MIRBuilder.getMF();
433  auto &MBB = MIRBuilder.getMBB();
434  auto DL = MF.getDataLayout();
435 
436  for (auto &Arg : F.args()) {
437  if (!isSupportedType(DL, TLI, Arg.getType()))
438  return false;
439  if (Arg.hasByValOrInAllocaAttr())
440  return false;
441  }
442 
443  CCAssignFn *AssignFn =
444  TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
445 
446  FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo(),
447  AssignFn);
448 
449  SmallVector<ArgInfo, 8> SplitArgInfos;
450  unsigned Idx = 0;
451  for (auto &Arg : F.args()) {
452  ArgInfo OrigArgInfo(VRegs[Idx], Arg.getType());
453 
454  setArgFlags(OrigArgInfo, Idx + AttributeList::FirstArgIndex, DL, F);
455  splitToValueTypes(OrigArgInfo, SplitArgInfos, MF);
456 
457  Idx++;
458  }
459 
460  if (!MBB.empty())
461  MIRBuilder.setInstr(*MBB.begin());
462 
463  if (!handleAssignments(MIRBuilder, SplitArgInfos, ArgHandler))
464  return false;
465 
466  // Move back to the end of the basic block.
467  MIRBuilder.setMBB(MBB);
468  return true;
469 }
470 
471 namespace {
472 
473 struct CallReturnHandler : public IncomingValueHandler {
474  CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
475  MachineInstrBuilder MIB, CCAssignFn *AssignFn)
476  : IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
477 
478  void markPhysRegUsed(unsigned PhysReg) override {
479  MIB.addDef(PhysReg, RegState::Implicit);
480  }
481 
483 };
484 
485 // FIXME: This should move to the ARMSubtarget when it supports all the opcodes.
486 unsigned getCallOpcode(const ARMSubtarget &STI, bool isDirect) {
487  if (isDirect)
488  return STI.isThumb() ? ARM::tBL : ARM::BL;
489 
490  if (STI.isThumb())
491  return ARM::tBLXr;
492 
493  if (STI.hasV5TOps())
494  return ARM::BLX;
495 
496  if (STI.hasV4TOps())
497  return ARM::BX_CALL;
498 
499  return ARM::BMOVPCRX_CALL;
500 }
501 } // end anonymous namespace
502 
504  MachineFunction &MF = MIRBuilder.getMF();
505  const auto &TLI = *getTLI<ARMTargetLowering>();
506  const auto &DL = MF.getDataLayout();
507  const auto &STI = MF.getSubtarget<ARMSubtarget>();
508  const TargetRegisterInfo *TRI = STI.getRegisterInfo();
510 
511  if (STI.genLongCalls())
512  return false;
513 
514  if (STI.isThumb1Only())
515  return false;
516 
517  auto CallSeqStart = MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN);
518 
519  // Create the call instruction so we can add the implicit uses of arg
520  // registers, but don't insert it yet.
521  bool IsDirect = !Info.Callee.isReg();
522  auto CallOpcode = getCallOpcode(STI, IsDirect);
523  auto MIB = MIRBuilder.buildInstrNoInsert(CallOpcode);
524 
525  bool IsThumb = STI.isThumb();
526  if (IsThumb)
527  MIB.add(predOps(ARMCC::AL));
528 
529  MIB.add(Info.Callee);
530  if (!IsDirect) {
531  auto CalleeReg = Info.Callee.getReg();
532  if (CalleeReg && !Register::isPhysicalRegister(CalleeReg)) {
533  unsigned CalleeIdx = IsThumb ? 2 : 0;
534  MIB->getOperand(CalleeIdx).setReg(constrainOperandRegClass(
535  MF, *TRI, MRI, *STI.getInstrInfo(), *STI.getRegBankInfo(),
536  *MIB.getInstr(), MIB->getDesc(), Info.Callee, CalleeIdx));
537  }
538  }
539 
540  MIB.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));
541 
542  bool IsVarArg = false;
543  SmallVector<ArgInfo, 8> ArgInfos;
544  for (auto Arg : Info.OrigArgs) {
545  if (!isSupportedType(DL, TLI, Arg.Ty))
546  return false;
547 
548  if (!Arg.IsFixed)
549  IsVarArg = true;
550 
551  if (Arg.Flags[0].isByVal())
552  return false;
553 
554  splitToValueTypes(Arg, ArgInfos, MF);
555  }
556 
557  auto ArgAssignFn = TLI.CCAssignFnForCall(Info.CallConv, IsVarArg);
558  OutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB, ArgAssignFn);
559  if (!handleAssignments(MIRBuilder, ArgInfos, ArgHandler))
560  return false;
561 
562  // Now we can add the actual call instruction to the correct basic block.
563  MIRBuilder.insertInstr(MIB);
564 
565  if (!Info.OrigRet.Ty->isVoidTy()) {
566  if (!isSupportedType(DL, TLI, Info.OrigRet.Ty))
567  return false;
568 
569  ArgInfos.clear();
570  splitToValueTypes(Info.OrigRet, ArgInfos, MF);
571  auto RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv, IsVarArg);
572  CallReturnHandler RetHandler(MIRBuilder, MRI, MIB, RetAssignFn);
573  if (!handleAssignments(MIRBuilder, ArgInfos, RetHandler))
574  return false;
575  }
576 
577  // We now know the size of the stack - update the ADJCALLSTACKDOWN
578  // accordingly.
579  CallSeqStart.addImm(ArgHandler.StackSize).addImm(0).add(predOps(ARMCC::AL));
580 
581  MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP)
582  .addImm(ArgHandler.StackSize)
583  .addImm(0)
584  .add(predOps(ARMCC::AL));
585 
586  return true;
587 }
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:111
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:641
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
MachineOperand Callee
Destination of the call.
Definition: CallLowering.h:77
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, ...
unsigned constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, const MachineOperand &RegMO, unsigned OpIdx)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
Definition: Utils.cpp:40
bool isThumb() const
Definition: ARMSubtarget.h:759
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Register getLocReg() const
bool hasV4TOps() const
Definition: ARMSubtarget.h:567
void addLiveIn(unsigned Reg, unsigned vreg=0)
addLiveIn - Add the specified register as a live-in.
bool isScalar() const
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:63
bool handleAssignments(MachineIRBuilder &MIRBuilder, SmallVectorImpl< ArgInfo > &Args, ValueHandler &Handler) const
Invoke Handler::assignArg on each of the given Args and then use Callback to move them to the assigne...
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...
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 const TargetRegisterInfo * TRI
F(f)
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, ArrayRef< Register > VRegs) const override
This hook behaves as the extended lowerReturn function, but for targets that do not support swifterro...
unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
static unsigned getCallOpcode(const Function &CallerF, bool IsIndirect, bool IsTailCall)
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
Definition: ValueTypes.cpp:264
ARMCallLowering(const ARMTargetLowering &TLI)
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
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
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:246
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:734
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:119
Analysis containing CSE Info
Definition: CSEInfo.cpp:20
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
bool isVoidTy() const
Return true if this is &#39;void&#39;.
Definition: Type.h:141
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
MachineRegisterInfo * getMRI()
Getter for MRI.
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:46
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.
Helper class to build MachineInstr.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
constexpr double e
Definition: MathExtras.h:57
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const FuncInfoTy &FuncInfo) const
bool lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const override
This hook must be implemented to lower the given call instruction, including argument and return valu...
MachineInstrBuilder buildGEP(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert Res = G_GEP Op0, Op1.
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:112
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.
The memory access writes data.
SmallVector< ArgInfo, 8 > OrigArgs
List of descriptors of the arguments passed to the function.
Definition: CallLowering.h:83
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
CCState - This class holds information needed while lowering arguments and return values...
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:390
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:212
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
CCValAssign - Represent assignment of one arg/retval to a location.
MachineInstrBuilder buildFrameIndex(const DstOp &Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
Definition: DataLayout.cpp:755
Promote Memory to Register
Definition: Mem2Reg.cpp:109
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:851
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.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
CallingConv::ID CallConv
Calling convention to be used for the call.
Definition: CallLowering.h:73
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef< ArrayRef< Register >> VRegs) const override
This hook must be implemented to lower the incoming (formal) arguments, described by VRegs...
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
uint32_t Size
Definition: Profile.cpp:46
static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI, Type *T)
bool hasV5TOps() const
Definition: ARMSubtarget.h:568
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegLoc() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
LLVM Value Representation.
Definition: Value.h:74
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...
MachineInstrBuilder buildMerge(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_MERGE_VALUES Op0, ...
SmallVector< Register, 4 > Regs
Definition: CallLowering.h:47
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
Type * getArrayElementType() const
Definition: Type.h:368
This file describes how to lower LLVM calls to machine code calls.
Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
Register getReg() const
getReg - Returns the register number.
ArgInfo OrigRet
Descriptor for the return type of the function.
Definition: CallLowering.h:80
iterator_range< arg_iterator > args()
Definition: Function.h:724
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
bool isStructTy() const
True if this is an instance of StructType.
Definition: Type.h:218
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:221