LLVM  4.0.0
AArch64CallLowering.cpp
Go to the documentation of this file.
1 //===-- llvm/lib/Target/AArch64/AArch64CallLowering.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 "AArch64CallLowering.h"
17 #include "AArch64ISelLowering.h"
18 
19 #include "llvm/CodeGen/Analysis.h"
27 using namespace llvm;
28 
29 #ifndef LLVM_BUILD_GLOBAL_ISEL
30 #error "This shouldn't be built without GISel"
31 #endif
32 
34  : CallLowering(&TLI) {
35 }
36 
39  : ValueHandler(MIRBuilder, MRI) {}
40 
41  unsigned getStackAddress(uint64_t Size, int64_t Offset,
42  MachinePointerInfo &MPO) override {
43  auto &MFI = MIRBuilder.getMF().getFrameInfo();
44  int FI = MFI.CreateFixedObject(Size, Offset, true);
45  MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
46  unsigned AddrReg = MRI.createGenericVirtualRegister(LLT::pointer(0, 64));
47  MIRBuilder.buildFrameIndex(AddrReg, FI);
48  return AddrReg;
49  }
50 
51  void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
52  CCValAssign &VA) override {
53  markPhysRegUsed(PhysReg);
54  MIRBuilder.buildCopy(ValVReg, PhysReg);
55  // FIXME: assert extension
56  }
57 
58  void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
59  MachinePointerInfo &MPO, CCValAssign &VA) override {
60  auto MMO = MIRBuilder.getMF().getMachineMemOperand(
62  0);
63  MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
64  }
65 
66  /// How the physical register gets marked varies between formal
67  /// parameters (it's a basic-block live-in), and a call instruction
68  /// (it's an implicit-def of the BL).
69  virtual void markPhysRegUsed(unsigned PhysReg) = 0;
70 };
71 
74  : IncomingArgHandler(MIRBuilder, MRI) {}
75 
76  void markPhysRegUsed(unsigned PhysReg) override {
77  MIRBuilder.getMBB().addLiveIn(PhysReg);
78  }
79 };
80 
84  : IncomingArgHandler(MIRBuilder, MRI), MIB(MIB) {}
85 
86  void markPhysRegUsed(unsigned PhysReg) override {
87  MIB.addDef(PhysReg, RegState::Implicit);
88  }
89 
91 };
92 
96  : ValueHandler(MIRBuilder, MRI), MIB(MIB) {}
97 
98  unsigned getStackAddress(uint64_t Size, int64_t Offset,
99  MachinePointerInfo &MPO) override {
100  LLT p0 = LLT::pointer(0, 64);
101  LLT s64 = LLT::scalar(64);
102  unsigned SPReg = MRI.createGenericVirtualRegister(p0);
103  MIRBuilder.buildCopy(SPReg, AArch64::SP);
104 
105  unsigned OffsetReg = MRI.createGenericVirtualRegister(s64);
106  MIRBuilder.buildConstant(OffsetReg, Offset);
107 
108  unsigned 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(unsigned ValVReg, unsigned PhysReg,
116  CCValAssign &VA) override {
117  MIB.addUse(PhysReg, RegState::Implicit);
118  unsigned ExtReg = extendRegister(ValVReg, VA);
119  MIRBuilder.buildCopy(PhysReg, ExtReg);
120  }
121 
122  void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
123  MachinePointerInfo &MPO, CCValAssign &VA) override {
124  auto MMO = MIRBuilder.getMF().getMachineMemOperand(
125  MPO, MachineMemOperand::MOStore, Size, 0);
126  MIRBuilder.buildStore(ValVReg, Addr, *MMO);
127  }
128 
130 };
131 
132 void AArch64CallLowering::splitToValueTypes(const ArgInfo &OrigArg,
133  SmallVectorImpl<ArgInfo> &SplitArgs,
134  const DataLayout &DL,
136  SplitArgTy PerformArgSplit) const {
137  const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
138  LLVMContext &Ctx = OrigArg.Ty->getContext();
139 
140  SmallVector<EVT, 4> SplitVTs;
142  ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
143 
144  if (SplitVTs.size() == 1) {
145  // No splitting to do, but we want to replace the original type (e.g. [1 x
146  // double] -> double).
147  SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx),
148  OrigArg.Flags);
149  return;
150  }
151 
152  unsigned FirstRegIdx = SplitArgs.size();
153  for (auto SplitVT : SplitVTs) {
154  // FIXME: set split flags if they're actually used (e.g. i128 on AAPCS).
155  Type *SplitTy = SplitVT.getTypeForEVT(Ctx);
156  SplitArgs.push_back(
157  ArgInfo{MRI.createGenericVirtualRegister(LLT{*SplitTy, DL}), SplitTy,
158  OrigArg.Flags});
159  }
160 
161  SmallVector<uint64_t, 4> BitOffsets;
162  for (auto Offset : Offsets)
163  BitOffsets.push_back(Offset * 8);
164 
165  SmallVector<unsigned, 8> SplitRegs;
166  for (auto I = &SplitArgs[FirstRegIdx]; I != SplitArgs.end(); ++I)
167  SplitRegs.push_back(I->Reg);
168 
169  PerformArgSplit(SplitRegs, BitOffsets);
170 }
171 
173  const Value *Val, unsigned VReg) const {
174  MachineFunction &MF = MIRBuilder.getMF();
175  const Function &F = *MF.getFunction();
176 
177  auto MIB = MIRBuilder.buildInstrNoInsert(AArch64::RET_ReallyLR);
178  assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg");
179  bool Success = true;
180  if (VReg) {
181  const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
182  CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
183  MachineRegisterInfo &MRI = MF.getRegInfo();
184  auto &DL = F.getParent()->getDataLayout();
185 
186  ArgInfo OrigArg{VReg, Val->getType()};
187  setArgFlags(OrigArg, AttributeSet::ReturnIndex, DL, F);
188 
189  SmallVector<ArgInfo, 8> SplitArgs;
190  splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
192  MIRBuilder.buildExtract(Regs, Offsets, VReg);
193  });
194 
195  OutgoingArgHandler Handler(MIRBuilder, MRI, MIB);
196  Success = handleAssignments(MIRBuilder, AssignFn, SplitArgs, Handler);
197  }
198 
199  MIRBuilder.insertInstr(MIB);
200  return Success;
201 }
202 
204  const Function &F,
205  ArrayRef<unsigned> VRegs) const {
206  auto &Args = F.getArgumentList();
207  MachineFunction &MF = MIRBuilder.getMF();
208  MachineBasicBlock &MBB = MIRBuilder.getMBB();
209  MachineRegisterInfo &MRI = MF.getRegInfo();
210  auto &DL = F.getParent()->getDataLayout();
211 
212  SmallVector<ArgInfo, 8> SplitArgs;
213  unsigned i = 0;
214  for (auto &Arg : Args) {
215  ArgInfo OrigArg{VRegs[i], Arg.getType()};
216  setArgFlags(OrigArg, i + 1, DL, F);
217  splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
219  MIRBuilder.buildSequence(VRegs[i], Regs, Offsets);
220  });
221  ++i;
222  }
223 
224  if (!MBB.empty())
225  MIRBuilder.setInstr(*MBB.begin());
226 
227  const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
228  CCAssignFn *AssignFn =
229  TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/false);
230 
231  FormalArgHandler Handler(MIRBuilder, MRI);
232  if (!handleAssignments(MIRBuilder, AssignFn, SplitArgs, Handler))
233  return false;
234 
235  // Move back to the end of the basic block.
236  MIRBuilder.setMBB(MBB);
237 
238  return true;
239 }
240 
242  const MachineOperand &Callee,
243  const ArgInfo &OrigRet,
244  ArrayRef<ArgInfo> OrigArgs) const {
245  MachineFunction &MF = MIRBuilder.getMF();
246  const Function &F = *MF.getFunction();
247  MachineRegisterInfo &MRI = MF.getRegInfo();
248  auto &DL = F.getParent()->getDataLayout();
249 
250  SmallVector<ArgInfo, 8> SplitArgs;
251  for (auto &OrigArg : OrigArgs) {
252  splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
254  MIRBuilder.buildExtract(Regs, Offsets, OrigArg.Reg);
255  });
256  }
257 
258  // Find out which ABI gets to decide where things go.
259  const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
260  CCAssignFn *CallAssignFn =
261  TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/false);
262 
263  // Create a temporarily-floating call instruction so we can add the implicit
264  // uses of arg registers.
265  auto MIB = MIRBuilder.buildInstrNoInsert(Callee.isReg() ? AArch64::BLR
266  : AArch64::BL);
267  MIB.addOperand(Callee);
268 
269  // Tell the call which registers are clobbered.
270  auto TRI = MF.getSubtarget().getRegisterInfo();
271  MIB.addRegMask(TRI->getCallPreservedMask(MF, F.getCallingConv()));
272 
273  // Do the actual argument marshalling.
274  SmallVector<unsigned, 8> PhysRegs;
275  OutgoingArgHandler Handler(MIRBuilder, MRI, MIB);
276  if (!handleAssignments(MIRBuilder, CallAssignFn, SplitArgs, Handler))
277  return false;
278 
279  // Now we can add the actual call instruction to the correct basic block.
280  MIRBuilder.insertInstr(MIB);
281 
282  // If Callee is a reg, since it is used by a target specific
283  // instruction, it must have a register class matching the
284  // constraint of that instruction.
285  if (Callee.isReg())
287  MF, *TRI, MRI, *MF.getSubtarget().getInstrInfo(),
288  *MF.getSubtarget().getRegBankInfo(), *MIB, MIB->getDesc(),
289  Callee.getReg(), 0));
290 
291  // Finally we can copy the returned value back into its virtual-register. In
292  // symmetry with the arugments, the physical register must be an
293  // implicit-define of the call instruction.
294  CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
295  if (OrigRet.Reg) {
296  SplitArgs.clear();
297 
298  SmallVector<uint64_t, 8> RegOffsets;
299  SmallVector<unsigned, 8> SplitRegs;
300  splitToValueTypes(OrigRet, SplitArgs, DL, MRI,
302  std::copy(Offsets.begin(), Offsets.end(),
303  std::back_inserter(RegOffsets));
304  std::copy(Regs.begin(), Regs.end(),
305  std::back_inserter(SplitRegs));
306  });
307 
308  CallReturnHandler Handler(MIRBuilder, MRI, MIB);
309  if (!handleAssignments(MIRBuilder, RetAssignFn, SplitArgs, Handler))
310  return false;
311 
312  if (!RegOffsets.empty())
313  MIRBuilder.buildSequence(OrigRet.Reg, SplitRegs, RegOffsets);
314  }
315 
316  return true;
317 }
MachineBasicBlock & getMBB()
Getter for the basic block we currently build.
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:102
size_t i
CCAssignFn * CCAssignFnForReturn(CallingConv::ID CC) const
Selects the correct CCAssignFn for a given CallingConvention value.
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...
OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, MachineInstrBuilder MIB)
iterator end() const
Definition: ArrayRef.h:130
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:777
static const MCPhysReg VRegs[32]
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
bool lowerCall(MachineIRBuilder &MIRBuilder, 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...
unsigned createGenericVirtualRegister(LLT Ty)
Create and return a new generic virtual register with low-level type Ty.
IncomingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:165
void markPhysRegUsed(unsigned PhysReg) override
How the physical register gets marked varies between formal parameters (it's a basic-block live-in)...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
virtual const RegisterBankInfo * getRegBankInfo() const
If the information for the register banks is available, return it.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:32
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:60
MachineInstrBuilder buildExtract(ArrayRef< unsigned > Results, ArrayRef< uint64_t > Indices, unsigned Src)
Build and insert `Res0<def>, ...
#define F(x, y, z)
Definition: MD5.cpp:51
MachineBasicBlock * MBB
const RegList & Regs
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
MachineFunction & getMF()
Getter for the function we currently build.
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:51
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...
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset)
Stack pointer relative access.
FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
unsigned const MachineRegisterInfo * MRI
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:48
void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, MachinePointerInfo &MPO, CCValAssign &VA) override
The specified value has been assigned to a stack location.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:279
Helper class to build MachineInstr.
unsigned getStackAddress(uint64_t Size, int64_t Offset, MachinePointerInfo &MPO) override
Materialize a VReg containing the address of the specified stack-based object.
uint32_t Offset
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
iterator begin() const
Definition: ArrayRef.h:129
void markPhysRegUsed(unsigned PhysReg) override
How the physical register gets marked varies between formal parameters (it's a basic-block live-in)...
Argument handling is mostly uniform between the four places that make these decisions: function forma...
Definition: CallLowering.h:49
This class contains a discriminated union of information about pointers in memory operands...
The memory access writes data.
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...
MachineInstrBuilder MIB
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:230
CCValAssign - Represent assignment of one arg/retval to a location.
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...
This file declares the MachineIRBuilder class.
CCAssignFn * CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const
Selects the correct CCAssignFn for a given CallingConvention value.
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.
#define Success
MachineInstrBuilder buildSequence(unsigned Res, ArrayRef< unsigned > Ops, ArrayRef< uint64_t > Indices)
Build and insert Res<def> = G_SEQUENCE Op0, Idx0...
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:384
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:119
void emplace_back(ArgTypes &&...Args)
Definition: SmallVector.h:635
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, MachinePointerInfo &MPO, CCValAssign &VA) override
The specified value has been assigned to a stack location.
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
#define I(x, y, z)
Definition: MD5.cpp:54
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:135
void setArgFlags(ArgInfo &Arg, unsigned OpNum, const DataLayout &DL, const FuncInfoTy &FuncInfo) const
The memory access always returns the same value (or traps).
void assignValueToReg(unsigned ValVReg, unsigned PhysReg, CCValAssign &VA) override
The specified value has been assigned to a physical register, handle the appropriate COPY (either to ...
This file describes how to lower LLVM calls to machine code calls.
MachineInstrBuilder MIB
unsigned getReg() const
getReg - Returns the register number.
unsigned getStackAddress(uint64_t Size, int64_t Offset, MachinePointerInfo &MPO) override
Materialize a VReg containing the address of the specified stack-based object.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetInstrInfo * getInstrInfo() const
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:537
LLVM Value Representation.
Definition: Value.h:71
static LLT pointer(uint16_t AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space (defaulting to 0).
Definition: LowLevelType.h:57
const ArgumentListType & getArgumentList() const
Get the underlying elements of the Function...
Definition: Function.h:499
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
AArch64CallLowering(const AArch64TargetLowering &TLI)
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
bool handleAssignments(MachineIRBuilder &MIRBuilder, CCAssignFn *AssignFn, ArrayRef< ArgInfo > Args, ValueHandler &Callback) const
Invoke the AssignFn on each of the given Args and then use Callback to move them to the assigned loca...
void assignValueToReg(unsigned ValVReg, unsigned PhysReg, CCValAssign &VA) override
The specified value has been assigned to a physical register, handle the appropriate COPY (either to ...
CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, MachineInstrBuilder MIB)