LLVM  7.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  if (Arg.hasByValOrInAllocaAttr())
441  return false;
442  }
443 
444  CCAssignFn *AssignFn =
445  TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
446 
447  FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo(),
448  AssignFn);
449 
450  SmallVector<ArgInfo, 8> ArgInfos;
451  SmallVector<unsigned, 4> SplitRegs;
452  unsigned Idx = 0;
453  for (auto &Arg : F.args()) {
454  ArgInfo AInfo(VRegs[Idx], Arg.getType());
455  setArgFlags(AInfo, Idx + AttributeList::FirstArgIndex, DL, F);
456 
457  SplitRegs.clear();
458 
459  splitToValueTypes(AInfo, ArgInfos, MF, [&](unsigned Reg, uint64_t Offset) {
460  SplitRegs.push_back(Reg);
461  });
462 
463  if (!SplitRegs.empty())
464  MIRBuilder.buildMerge(VRegs[Idx], SplitRegs);
465 
466  Idx++;
467  }
468 
469  if (!MBB.empty())
470  MIRBuilder.setInstr(*MBB.begin());
471 
472  return handleAssignments(MIRBuilder, ArgInfos, ArgHandler);
473 }
474 
475 namespace {
476 
477 struct CallReturnHandler : public IncomingValueHandler {
478  CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
479  MachineInstrBuilder MIB, CCAssignFn *AssignFn)
480  : IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
481 
482  void markPhysRegUsed(unsigned PhysReg) override {
483  MIB.addDef(PhysReg, RegState::Implicit);
484  }
485 
487 };
488 
489 } // end anonymous namespace
490 
492  CallingConv::ID CallConv,
493  const MachineOperand &Callee,
494  const ArgInfo &OrigRet,
495  ArrayRef<ArgInfo> OrigArgs) const {
496  MachineFunction &MF = MIRBuilder.getMF();
497  const auto &TLI = *getTLI<ARMTargetLowering>();
498  const auto &DL = MF.getDataLayout();
499  const auto &STI = MF.getSubtarget<ARMSubtarget>();
500  const TargetRegisterInfo *TRI = STI.getRegisterInfo();
502 
503  if (STI.genLongCalls())
504  return false;
505 
506  auto CallSeqStart = MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN);
507 
508  // Create the call instruction so we can add the implicit uses of arg
509  // registers, but don't insert it yet.
510  bool isDirect = !Callee.isReg();
511  auto CallOpcode =
512  isDirect ? ARM::BL
513  : STI.hasV5TOps()
514  ? ARM::BLX
515  : STI.hasV4TOps() ? ARM::BX_CALL : ARM::BMOVPCRX_CALL;
516  auto MIB = MIRBuilder.buildInstrNoInsert(CallOpcode)
517  .add(Callee)
518  .addRegMask(TRI->getCallPreservedMask(MF, CallConv));
519  if (Callee.isReg()) {
520  auto CalleeReg = Callee.getReg();
521  if (CalleeReg && !TRI->isPhysicalRegister(CalleeReg))
522  MIB->getOperand(0).setReg(constrainOperandRegClass(
523  MF, *TRI, MRI, *STI.getInstrInfo(), *STI.getRegBankInfo(),
524  *MIB.getInstr(), MIB->getDesc(), CalleeReg, 0));
525  }
526 
527  SmallVector<ArgInfo, 8> ArgInfos;
528  for (auto Arg : OrigArgs) {
529  if (!isSupportedType(DL, TLI, Arg.Ty))
530  return false;
531 
532  if (!Arg.IsFixed)
533  return false;
534 
535  if (Arg.Flags.isByVal())
536  return false;
537 
539  splitToValueTypes(Arg, ArgInfos, MF, [&](unsigned Reg, uint64_t Offset) {
540  Regs.push_back(Reg);
541  });
542 
543  if (Regs.size() > 1)
544  MIRBuilder.buildUnmerge(Regs, Arg.Reg);
545  }
546 
547  auto ArgAssignFn = TLI.CCAssignFnForCall(CallConv, /*IsVarArg=*/false);
548  OutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB, ArgAssignFn);
549  if (!handleAssignments(MIRBuilder, ArgInfos, ArgHandler))
550  return false;
551 
552  // Now we can add the actual call instruction to the correct basic block.
553  MIRBuilder.insertInstr(MIB);
554 
555  if (!OrigRet.Ty->isVoidTy()) {
556  if (!isSupportedType(DL, TLI, OrigRet.Ty))
557  return false;
558 
559  ArgInfos.clear();
560  SmallVector<unsigned, 8> SplitRegs;
561  splitToValueTypes(OrigRet, ArgInfos, MF,
562  [&](unsigned Reg, uint64_t Offset) {
563  SplitRegs.push_back(Reg);
564  });
565 
566  auto RetAssignFn = TLI.CCAssignFnForReturn(CallConv, /*IsVarArg=*/false);
567  CallReturnHandler RetHandler(MIRBuilder, MRI, MIB, RetAssignFn);
568  if (!handleAssignments(MIRBuilder, ArgInfos, RetHandler))
569  return false;
570 
571  if (!SplitRegs.empty()) {
572  // We have split the value and allocated each individual piece, now build
573  // it up again.
574  MIRBuilder.buildMerge(OrigRet.Reg, SplitRegs);
575  }
576  }
577 
578  // We now know the size of the stack - update the ADJCALLSTACKDOWN
579  // accordingly.
580  CallSeqStart.addImm(ArgHandler.StackSize).addImm(0).add(predOps(ARMCC::AL));
581 
582  MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP)
583  .addImm(ArgHandler.StackSize)
584  .addImm(0)
585  .add(predOps(ARMCC::AL));
586 
587  return true;
588 }
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:111
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
MachineInstrBuilder buildGEP(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res = 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:944
unsigned getValNo() const
static const MCPhysReg VRegs[32]
MachineInstrBuilder buildTrunc(unsigned Res, unsigned Op)
Build and insert Res = 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:677
#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:84
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
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 = 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:862
MachineInstrBuilder buildCopy(unsigned Res, unsigned Op)
Build and insert Res = 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:713
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: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:654
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, ...
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: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 = 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 = G_MERGE_VALUES Op0, ...
iterator_range< arg_iterator > args()
Definition: Function.h:667
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