LLVM  6.0.0svn
ARMCallLowering.cpp
Go to the documentation of this file.
1 //===- llvm/lib/Target/ARM/ARMCallLowering.cpp - Call lowering ------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 /// This file implements the lowering of LLVM calls to machine code calls for
12 /// GlobalISel.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "ARMCallLowering.h"
17 #include "ARMBaseInstrInfo.h"
18 #include "ARMISelLowering.h"
19 #include "ARMSubtarget.h"
20 #include "Utils/ARMBaseInfo.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/CodeGen/Analysis.h"
38 #include "llvm/IR/Attributes.h"
39 #include "llvm/IR/DataLayout.h"
40 #include "llvm/IR/DerivedTypes.h"
41 #include "llvm/IR/Function.h"
42 #include "llvm/IR/Type.h"
43 #include "llvm/IR/Value.h"
44 #include "llvm/Support/Casting.h"
46 #include <algorithm>
47 #include <cassert>
48 #include <cstdint>
49 #include <utility>
50 
51 using namespace llvm;
52 
54  : CallLowering(&TLI) {}
55 
56 static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI,
57  Type *T) {
58  if (T->isArrayTy())
59  return true;
60 
61  if (T->isStructTy()) {
62  // For now we only allow homogeneous structs that we can manipulate with
63  // G_MERGE_VALUES and G_UNMERGE_VALUES
64  auto StructT = cast<StructType>(T);
65  for (unsigned i = 1, e = StructT->getNumElements(); i != e; ++i)
66  if (StructT->getElementType(i) != StructT->getElementType(0))
67  return false;
68  return true;
69  }
70 
71  EVT VT = TLI.getValueType(DL, T, true);
72  if (!VT.isSimple() || VT.isVector() ||
73  !(VT.isInteger() || VT.isFloatingPoint()))
74  return false;
75 
76  unsigned VTSize = VT.getSimpleVT().getSizeInBits();
77 
78  if (VTSize == 64)
79  // FIXME: Support i64 too
80  return VT.isFloatingPoint();
81 
82  return VTSize == 1 || VTSize == 8 || VTSize == 16 || VTSize == 32;
83 }
84 
85 namespace {
86 
87 /// Helper class for values going out through an ABI boundary (used for handling
88 /// function return values and call parameters).
89 struct OutgoingValueHandler : public CallLowering::ValueHandler {
90  OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
91  MachineInstrBuilder &MIB, CCAssignFn *AssignFn)
92  : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
93 
94  unsigned getStackAddress(uint64_t Size, int64_t Offset,
95  MachinePointerInfo &MPO) override {
96  assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
97  "Unsupported size");
98 
99  LLT p0 = LLT::pointer(0, 32);
100  LLT s32 = LLT::scalar(32);
101  unsigned SPReg = MRI.createGenericVirtualRegister(p0);
102  MIRBuilder.buildCopy(SPReg, ARM::SP);
103 
104  unsigned OffsetReg = MRI.createGenericVirtualRegister(s32);
105  MIRBuilder.buildConstant(OffsetReg, Offset);
106 
107  unsigned AddrReg = MRI.createGenericVirtualRegister(p0);
108  MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
109 
110  MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
111  return AddrReg;
112  }
113 
114  void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
115  CCValAssign &VA) override {
116  assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
117  assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
118 
119  assert(VA.getValVT().getSizeInBits() <= 64 && "Unsupported value size");
120  assert(VA.getLocVT().getSizeInBits() <= 64 && "Unsupported location size");
121 
122  unsigned ExtReg = extendRegister(ValVReg, VA);
123  MIRBuilder.buildCopy(PhysReg, ExtReg);
124  MIB.addUse(PhysReg, RegState::Implicit);
125  }
126 
127  void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
128  MachinePointerInfo &MPO, CCValAssign &VA) override {
129  assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
130  "Unsupported size");
131 
132  unsigned ExtReg = extendRegister(ValVReg, VA);
133  auto MMO = MIRBuilder.getMF().getMachineMemOperand(
135  /* Alignment */ 0);
136  MIRBuilder.buildStore(ExtReg, Addr, *MMO);
137  }
138 
139  unsigned assignCustomValue(const CallLowering::ArgInfo &Arg,
140  ArrayRef<CCValAssign> VAs) override {
141  CCValAssign VA = VAs[0];
142  assert(VA.needsCustom() && "Value doesn't need custom handling");
143  assert(VA.getValVT() == MVT::f64 && "Unsupported type");
144 
145  CCValAssign NextVA = VAs[1];
146  assert(NextVA.needsCustom() && "Value doesn't need custom handling");
147  assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
148 
149  assert(VA.getValNo() == NextVA.getValNo() &&
150  "Values belong to different arguments");
151 
152  assert(VA.isRegLoc() && "Value should be in reg");
153  assert(NextVA.isRegLoc() && "Value should be in reg");
154 
155  unsigned NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
157  MIRBuilder.buildUnmerge(NewRegs, Arg.Reg);
158 
159  bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
160  if (!IsLittle)
161  std::swap(NewRegs[0], NewRegs[1]);
162 
163  assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
164  assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
165 
166  return 1;
167  }
168 
169  bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
170  CCValAssign::LocInfo LocInfo,
171  const CallLowering::ArgInfo &Info, CCState &State) override {
172  if (AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State))
173  return true;
174 
175  StackSize =
176  std::max(StackSize, static_cast<uint64_t>(State.getNextStackOffset()));
177  return false;
178  }
179 
180  MachineInstrBuilder &MIB;
181  uint64_t StackSize = 0;
182 };
183 
184 } // end anonymous namespace
185 
186 void ARMCallLowering::splitToValueTypes(
187  const ArgInfo &OrigArg, SmallVectorImpl<ArgInfo> &SplitArgs,
188  MachineFunction &MF, const SplitArgTy &PerformArgSplit) const {
189  const ARMTargetLowering &TLI = *getTLI<ARMTargetLowering>();
190  LLVMContext &Ctx = OrigArg.Ty->getContext();
191  const DataLayout &DL = MF.getDataLayout();
193  const Function *F = MF.getFunction();
194 
195  SmallVector<EVT, 4> SplitVTs;
197  ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
198 
199  if (SplitVTs.size() == 1) {
200  // Even if there is no splitting to do, we still want to replace the
201  // original type (e.g. pointer type -> integer).
202  auto Flags = OrigArg.Flags;
203  unsigned OriginalAlignment = DL.getABITypeAlignment(OrigArg.Ty);
204  Flags.setOrigAlign(OriginalAlignment);
205  SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx), Flags,
206  OrigArg.IsFixed);
207  return;
208  }
209 
210  unsigned FirstRegIdx = SplitArgs.size();
211  for (unsigned i = 0, e = SplitVTs.size(); i != e; ++i) {
212  EVT SplitVT = SplitVTs[i];
213  Type *SplitTy = SplitVT.getTypeForEVT(Ctx);
214  auto Flags = OrigArg.Flags;
215 
216  unsigned OriginalAlignment = DL.getABITypeAlignment(SplitTy);
217  Flags.setOrigAlign(OriginalAlignment);
218 
219  bool NeedsConsecutiveRegisters =
221  SplitTy, F->getCallingConv(), F->isVarArg());
222  if (NeedsConsecutiveRegisters) {
223  Flags.setInConsecutiveRegs();
224  if (i == e - 1)
225  Flags.setInConsecutiveRegsLast();
226  }
227 
228  SplitArgs.push_back(
229  ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*SplitTy, DL)),
230  SplitTy, Flags, OrigArg.IsFixed});
231  }
232 
233  for (unsigned i = 0; i < Offsets.size(); ++i)
234  PerformArgSplit(SplitArgs[FirstRegIdx + i].Reg, Offsets[i] * 8);
235 }
236 
237 /// Lower the return value for the already existing \p Ret. This assumes that
238 /// \p MIRBuilder's insertion point is correct.
239 bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
240  const Value *Val, unsigned VReg,
241  MachineInstrBuilder &Ret) const {
242  if (!Val)
243  // Nothing to do here.
244  return true;
245 
246  auto &MF = MIRBuilder.getMF();
247  const auto &F = *MF.getFunction();
248 
249  auto DL = MF.getDataLayout();
250  auto &TLI = *getTLI<ARMTargetLowering>();
251  if (!isSupportedType(DL, TLI, Val->getType()))
252  return false;
253 
254  SmallVector<ArgInfo, 4> SplitVTs;
256  ArgInfo RetInfo(VReg, Val->getType());
258  splitToValueTypes(RetInfo, SplitVTs, MF, [&](unsigned Reg, uint64_t Offset) {
259  Regs.push_back(Reg);
260  });
261 
262  if (Regs.size() > 1)
263  MIRBuilder.buildUnmerge(Regs, VReg);
264 
265  CCAssignFn *AssignFn =
266  TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
267 
268  OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret, AssignFn);
269  return handleAssignments(MIRBuilder, SplitVTs, RetHandler);
270 }
271 
273  const Value *Val, unsigned VReg) const {
274  assert(!Val == !VReg && "Return value without a vreg");
275 
276  auto const &ST = MIRBuilder.getMF().getSubtarget<ARMSubtarget>();
277  unsigned Opcode = ST.getReturnOpcode();
278  auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL));
279 
280  if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret))
281  return false;
282 
283  MIRBuilder.insertInstr(Ret);
284  return true;
285 }
286 
287 namespace {
288 
289 /// Helper class for values coming in through an ABI boundary (used for handling
290 /// formal arguments and call return values).
291 struct IncomingValueHandler : public CallLowering::ValueHandler {
292  IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
293  CCAssignFn AssignFn)
294  : ValueHandler(MIRBuilder, MRI, AssignFn) {}
295 
296  unsigned getStackAddress(uint64_t Size, int64_t Offset,
297  MachinePointerInfo &MPO) override {
298  assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
299  "Unsupported size");
300 
301  auto &MFI = MIRBuilder.getMF().getFrameInfo();
302 
303  int FI = MFI.CreateFixedObject(Size, Offset, true);
304  MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
305 
306  unsigned AddrReg =
308  MIRBuilder.buildFrameIndex(AddrReg, FI);
309 
310  return AddrReg;
311  }
312 
313  void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
314  MachinePointerInfo &MPO, CCValAssign &VA) override {
315  assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
316  "Unsupported size");
317 
318  if (VA.getLocInfo() == CCValAssign::SExt ||
319  VA.getLocInfo() == CCValAssign::ZExt) {
320  // If the value is zero- or sign-extended, its size becomes 4 bytes, so
321  // that's what we should load.
322  Size = 4;
323  assert(MRI.getType(ValVReg).isScalar() && "Only scalars supported atm");
324 
325  auto LoadVReg = MRI.createGenericVirtualRegister(LLT::scalar(32));
326  buildLoad(LoadVReg, Addr, Size, /* Alignment */ 0, MPO);
327  MIRBuilder.buildTrunc(ValVReg, LoadVReg);
328  } else {
329  // If the value is not extended, a simple load will suffice.
330  buildLoad(ValVReg, Addr, Size, /* Alignment */ 0, MPO);
331  }
332  }
333 
334  void buildLoad(unsigned Val, unsigned Addr, uint64_t Size, unsigned Alignment,
335  MachinePointerInfo &MPO) {
336  auto MMO = MIRBuilder.getMF().getMachineMemOperand(
337  MPO, MachineMemOperand::MOLoad, Size, Alignment);
338  MIRBuilder.buildLoad(Val, Addr, *MMO);
339  }
340 
341  void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
342  CCValAssign &VA) override {
343  assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
344  assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
345 
346  auto ValSize = VA.getValVT().getSizeInBits();
347  auto LocSize = VA.getLocVT().getSizeInBits();
348 
349  assert(ValSize <= 64 && "Unsupported value size");
350  assert(LocSize <= 64 && "Unsupported location size");
351 
352  markPhysRegUsed(PhysReg);
353  if (ValSize == LocSize) {
354  MIRBuilder.buildCopy(ValVReg, PhysReg);
355  } else {
356  assert(ValSize < LocSize && "Extensions not supported");
357 
358  // We cannot create a truncating copy, nor a trunc of a physical register.
359  // Therefore, we need to copy the content of the physical register into a
360  // virtual one and then truncate that.
361  auto PhysRegToVReg =
363  MIRBuilder.buildCopy(PhysRegToVReg, PhysReg);
364  MIRBuilder.buildTrunc(ValVReg, PhysRegToVReg);
365  }
366  }
367 
368  unsigned assignCustomValue(const ARMCallLowering::ArgInfo &Arg,
369  ArrayRef<CCValAssign> VAs) override {
370  CCValAssign VA = VAs[0];
371  assert(VA.needsCustom() && "Value doesn't need custom handling");
372  assert(VA.getValVT() == MVT::f64 && "Unsupported type");
373 
374  CCValAssign NextVA = VAs[1];
375  assert(NextVA.needsCustom() && "Value doesn't need custom handling");
376  assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
377 
378  assert(VA.getValNo() == NextVA.getValNo() &&
379  "Values belong to different arguments");
380 
381  assert(VA.isRegLoc() && "Value should be in reg");
382  assert(NextVA.isRegLoc() && "Value should be in reg");
383 
384  unsigned NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
386 
387  assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
388  assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
389 
390  bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
391  if (!IsLittle)
392  std::swap(NewRegs[0], NewRegs[1]);
393 
394  MIRBuilder.buildMerge(Arg.Reg, NewRegs);
395 
396  return 1;
397  }
398 
399  /// Marking a physical register as used is different between formal
400  /// parameters, where it's a basic block live-in, and call returns, where it's
401  /// an implicit-def of the call instruction.
402  virtual void markPhysRegUsed(unsigned PhysReg) = 0;
403 };
404 
405 struct FormalArgHandler : public IncomingValueHandler {
406  FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
407  CCAssignFn AssignFn)
408  : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
409 
410  void markPhysRegUsed(unsigned PhysReg) override {
411  MIRBuilder.getMBB().addLiveIn(PhysReg);
412  }
413 };
414 
415 } // end anonymous namespace
416 
418  const Function &F,
419  ArrayRef<unsigned> VRegs) const {
420  auto &TLI = *getTLI<ARMTargetLowering>();
421  auto Subtarget = TLI.getSubtarget();
422 
423  if (Subtarget->isThumb())
424  return false;
425 
426  // Quick exit if there aren't any args
427  if (F.arg_empty())
428  return true;
429 
430  if (F.isVarArg())
431  return false;
432 
433  auto &MF = MIRBuilder.getMF();
434  auto &MBB = MIRBuilder.getMBB();
435  auto DL = MF.getDataLayout();
436 
437  for (auto &Arg : F.args())
438  if (!isSupportedType(DL, TLI, Arg.getType()))
439  return false;
440 
441  CCAssignFn *AssignFn =
442  TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
443 
444  FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo(),
445  AssignFn);
446 
447  SmallVector<ArgInfo, 8> ArgInfos;
448  SmallVector<unsigned, 4> SplitRegs;
449  unsigned Idx = 0;
450  for (auto &Arg : F.args()) {
451  ArgInfo AInfo(VRegs[Idx], Arg.getType());
452  setArgFlags(AInfo, Idx + AttributeList::FirstArgIndex, DL, F);
453 
454  SplitRegs.clear();
455 
456  splitToValueTypes(AInfo, ArgInfos, MF, [&](unsigned Reg, uint64_t Offset) {
457  SplitRegs.push_back(Reg);
458  });
459 
460  if (!SplitRegs.empty())
461  MIRBuilder.buildMerge(VRegs[Idx], SplitRegs);
462 
463  Idx++;
464  }
465 
466  if (!MBB.empty())
467  MIRBuilder.setInstr(*MBB.begin());
468 
469  return handleAssignments(MIRBuilder, ArgInfos, ArgHandler);
470 }
471 
472 namespace {
473 
474 struct CallReturnHandler : public IncomingValueHandler {
475  CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
476  MachineInstrBuilder MIB, CCAssignFn *AssignFn)
477  : IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
478 
479  void markPhysRegUsed(unsigned PhysReg) override {
480  MIB.addDef(PhysReg, RegState::Implicit);
481  }
482 
484 };
485 
486 } // end anonymous namespace
487 
489  CallingConv::ID CallConv,
490  const MachineOperand &Callee,
491  const ArgInfo &OrigRet,
492  ArrayRef<ArgInfo> OrigArgs) const {
493  MachineFunction &MF = MIRBuilder.getMF();
494  const auto &TLI = *getTLI<ARMTargetLowering>();
495  const auto &DL = MF.getDataLayout();
496  const auto &STI = MF.getSubtarget<ARMSubtarget>();
497  const TargetRegisterInfo *TRI = STI.getRegisterInfo();
499 
500  if (STI.genLongCalls())
501  return false;
502 
503  auto CallSeqStart = MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN);
504 
505  // Create the call instruction so we can add the implicit uses of arg
506  // registers, but don't insert it yet.
507  bool isDirect = !Callee.isReg();
508  auto CallOpcode =
509  isDirect ? ARM::BL
510  : STI.hasV5TOps()
511  ? ARM::BLX
512  : STI.hasV4TOps() ? ARM::BX_CALL : ARM::BMOVPCRX_CALL;
513  auto MIB = MIRBuilder.buildInstrNoInsert(CallOpcode)
514  .add(Callee)
515  .addRegMask(TRI->getCallPreservedMask(MF, CallConv));
516  if (Callee.isReg()) {
517  auto CalleeReg = Callee.getReg();
518  if (CalleeReg && !TRI->isPhysicalRegister(CalleeReg))
519  MIB->getOperand(0).setReg(constrainOperandRegClass(
520  MF, *TRI, MRI, *STI.getInstrInfo(), *STI.getRegBankInfo(),
521  *MIB.getInstr(), MIB->getDesc(), CalleeReg, 0));
522  }
523 
524  SmallVector<ArgInfo, 8> ArgInfos;
525  for (auto Arg : OrigArgs) {
526  if (!isSupportedType(DL, TLI, Arg.Ty))
527  return false;
528 
529  if (!Arg.IsFixed)
530  return false;
531 
533  splitToValueTypes(Arg, ArgInfos, MF, [&](unsigned Reg, uint64_t Offset) {
534  Regs.push_back(Reg);
535  });
536 
537  if (Regs.size() > 1)
538  MIRBuilder.buildUnmerge(Regs, Arg.Reg);
539  }
540 
541  auto ArgAssignFn = TLI.CCAssignFnForCall(CallConv, /*IsVarArg=*/false);
542  OutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB, ArgAssignFn);
543  if (!handleAssignments(MIRBuilder, ArgInfos, ArgHandler))
544  return false;
545 
546  // Now we can add the actual call instruction to the correct basic block.
547  MIRBuilder.insertInstr(MIB);
548 
549  if (!OrigRet.Ty->isVoidTy()) {
550  if (!isSupportedType(DL, TLI, OrigRet.Ty))
551  return false;
552 
553  ArgInfos.clear();
554  SmallVector<unsigned, 8> SplitRegs;
555  splitToValueTypes(OrigRet, ArgInfos, MF,
556  [&](unsigned Reg, uint64_t Offset) {
557  SplitRegs.push_back(Reg);
558  });
559 
560  auto RetAssignFn = TLI.CCAssignFnForReturn(CallConv, /*IsVarArg=*/false);
561  CallReturnHandler RetHandler(MIRBuilder, MRI, MIB, RetAssignFn);
562  if (!handleAssignments(MIRBuilder, ArgInfos, RetHandler))
563  return false;
564 
565  if (!SplitRegs.empty()) {
566  // We have split the value and allocated each individual piece, now build
567  // it up again.
568  MIRBuilder.buildMerge(OrigRet.Reg, SplitRegs);
569  }
570  }
571 
572  // We now know the size of the stack - update the ADJCALLSTACKDOWN
573  // accordingly.
574  CallSeqStart.addImm(ArgHandler.StackSize).addImm(0).add(predOps(ARMCC::AL));
575 
576  MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP)
577  .addImm(ArgHandler.StackSize)
578  .addImm(0)
579  .add(predOps(ARMCC::AL));
580 
581  return true;
582 }
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:158
MachineBasicBlock & getMBB()
Getter for the basic block we currently build.
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:109
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
MachineInstrBuilder buildGEP(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res<def> = G_GEP Op0, Op1.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
unsigned constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const MCInstrDesc &II, unsigned Reg, unsigned OpIdx)
Try to constrain Reg so that it is usable by argument OpIdx of the provided MCInstrDesc II...
Definition: Utils.cpp:46
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:136
bool isScalar() const
unsigned getReg() const
getReg - Returns the register number.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:253
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:935
unsigned getValNo() const
static const MCPhysReg VRegs[32]
MachineInstrBuilder buildTrunc(unsigned Res, unsigned Op)
Build and insert Res<def> = G_TRUNC Op.
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition: ValueTypes.h:141
F(f)
unsigned createGenericVirtualRegister(LLT Ty)
Create and return a new generic virtual register with low-level type Ty.
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:136
MachineInstrBuilder buildStore(unsigned Val, unsigned Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val, unsigned VReg) const override
This hook must be implemented to lower outgoing return values, described by Val, into the specified v...
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:42
Reg
All possible values of the reg field in the ModR/M byte.
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:245
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:631
#define T
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don&#39;t insert <empty> = Opcode <empty>.
const RegList & Regs
void setArgFlags(ArgInfo &Arg, unsigned OpNum, const DataLayout &DL, const FuncInfoTy &FuncInfo) const
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:33
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
amdgpu Simplify well known AMD library false Value * Callee
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:85
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:141
bool handleAssignments(MachineIRBuilder &MIRBuilder, ArrayRef< ArgInfo > Args, ValueHandler &Callback) const
Invoke Handler::assignArg on each of the given Args and then use Callback to move them to the assigne...
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:46
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:69
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.
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
Extended Value Type.
Definition: ValueTypes.h:34
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
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<def> = 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.
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:194
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:864
MachineInstrBuilder buildCopy(unsigned Res, unsigned Op)
Build and insert Res<def> = COPY Op.
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:682
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:923
amdgpu Simplify well known AMD library false Value Value * Arg
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:151
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
void emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:656
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:61
MachineInstrBuilder buildConstant(unsigned Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
LLT getType(unsigned VReg) const
Get the low-level type of VReg or LLT{} if VReg is not a generic (target independent) virtual registe...
static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI, Type *T)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineInstrBuilder buildUnmerge(ArrayRef< unsigned > Res, unsigned Op)
Build and insert Res0<def>, ...
bool isRegLoc() const
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
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:73
static LLT pointer(uint16_t AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space (defaulting to 0).
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr, MachineMemOperand &MMO)
Build and insert Res<def> = 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.
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:126
MachineInstrBuilder buildMerge(unsigned Res, ArrayRef< unsigned > Ops)
Build and insert Res<def> = G_MERGE_VALUES Op0, ...
iterator_range< arg_iterator > args()
Definition: Function.h:621
bool isStructTy() const
True if this is an instance of StructType.
Definition: Type.h:215
bool isArrayTy() const
True if this is an instance of ArrayType.
Definition: Type.h:218