blob: d694a078fa43dc97315485e54e93167029b03d5e [file] [log] [blame]
Quentin Colombetba2a0162016-02-16 19:26:02 +00001//===-- 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/GlobalISel/MachineIRBuilder.h"
Tim Northoverb18ea162016-09-20 15:20:36 +000020#include "llvm/CodeGen/Analysis.h"
Quentin Colombetba2a0162016-02-16 19:26:02 +000021#include "llvm/CodeGen/MachineInstrBuilder.h"
Tim Northoverb18ea162016-09-20 15:20:36 +000022#include "llvm/CodeGen/MachineRegisterInfo.h"
Tim Northover406024a2016-08-10 21:44:01 +000023#include "llvm/Target/TargetRegisterInfo.h"
24#include "llvm/Target/TargetSubtargetInfo.h"
Quentin Colombetba2a0162016-02-16 19:26:02 +000025using namespace llvm;
26
Quentin Colombet789ad562016-04-07 20:47:51 +000027#ifndef LLVM_BUILD_GLOBAL_ISEL
Quentin Colombet6cc73ce2016-04-07 20:49:15 +000028#error "This shouldn't be built without GISel"
Quentin Colombet789ad562016-04-07 20:47:51 +000029#endif
30
Quentin Colombetba2a0162016-02-16 19:26:02 +000031AArch64CallLowering::AArch64CallLowering(const AArch64TargetLowering &TLI)
32 : CallLowering(&TLI) {
33}
34
Tim Northover406024a2016-08-10 21:44:01 +000035bool AArch64CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder,
36 CCAssignFn *AssignFn,
Tim Northover9a467182016-09-21 12:57:45 +000037 ArrayRef<ArgInfo> Args,
Tim Northovera5e38fa2016-09-22 13:49:25 +000038 ValueHandler &Handler) const {
Quentin Colombetba2a0162016-02-16 19:26:02 +000039 MachineFunction &MF = MIRBuilder.getMF();
40 const Function &F = *MF.getFunction();
41
42 SmallVector<CCValAssign, 16> ArgLocs;
43 CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
44
Tim Northover9a467182016-09-21 12:57:45 +000045 unsigned NumArgs = Args.size();
46 for (unsigned i = 0; i != NumArgs; ++i) {
47 MVT CurVT = MVT::getVT(Args[i].Ty);
48 if (AssignFn(i, CurVT, CurVT, CCValAssign::Full, Args[i].Flags, CCInfo))
Quentin Colombeta94caa52016-08-27 00:18:28 +000049 return false;
Quentin Colombetba2a0162016-02-16 19:26:02 +000050 }
Tim Northovera5e38fa2016-09-22 13:49:25 +000051
Tim Northover9a467182016-09-21 12:57:45 +000052 for (unsigned i = 0, e = Args.size(); i != e; ++i) {
Quentin Colombetba2a0162016-02-16 19:26:02 +000053 CCValAssign &VA = ArgLocs[i];
54
Tim Northovera5e38fa2016-09-22 13:49:25 +000055 if (VA.isRegLoc())
56 Handler.assignValueToReg(Args[i].Reg, VA.getLocReg(), VA);
57 else if (VA.isMemLoc()) {
58 unsigned Size = VA.getValVT().getSizeInBits() / 8;
59 unsigned Offset = VA.getLocMemOffset();
60 MachinePointerInfo MPO;
61 unsigned StackAddr = Handler.getStackAddress(Size, Offset, MPO);
62 Handler.assignValueToAddress(Args[i].Reg, StackAddr, Size, MPO, VA);
63 } else {
64 // FIXME: Support byvals and other weirdness
Quentin Colombeta94caa52016-08-27 00:18:28 +000065 return false;
Tim Northovera5e38fa2016-09-22 13:49:25 +000066 }
Quentin Colombetba2a0162016-02-16 19:26:02 +000067 }
68 return true;
69}
Tim Northover406024a2016-08-10 21:44:01 +000070
Tim Northovera5e38fa2016-09-22 13:49:25 +000071unsigned AArch64CallLowering::ValueHandler::extendRegister(unsigned ValReg,
72 CCValAssign &VA) {
73 LLT LocTy{VA.getLocVT()};
74 switch (VA.getLocInfo()) {
75 default: break;
76 case CCValAssign::Full:
77 case CCValAssign::BCvt:
78 // FIXME: bitconverting between vector types may or may not be a
79 // nop in big-endian situations.
80 return ValReg;
81 case CCValAssign::AExt:
82 assert(!VA.getLocVT().isVector() && "unexpected vector extend");
83 // Otherwise, it's a nop.
84 return ValReg;
85 case CCValAssign::SExt: {
86 unsigned NewReg = MRI.createGenericVirtualRegister(LocTy);
87 MIRBuilder.buildSExt(NewReg, ValReg);
88 return NewReg;
89 }
90 case CCValAssign::ZExt: {
91 unsigned NewReg = MRI.createGenericVirtualRegister(LocTy);
92 MIRBuilder.buildZExt(NewReg, ValReg);
93 return NewReg;
94 }
95 }
96 llvm_unreachable("unable to extend register");
97}
98
99struct IncomingArgHandler : public AArch64CallLowering::ValueHandler {
100 IncomingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
101 : ValueHandler(MIRBuilder, MRI) {}
102
103 unsigned getStackAddress(uint64_t Size, int64_t Offset,
104 MachinePointerInfo &MPO) override {
105 auto &MFI = MIRBuilder.getMF().getFrameInfo();
106 int FI = MFI.CreateFixedObject(Size, Offset, true);
107 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
108 unsigned AddrReg = MRI.createGenericVirtualRegister(LLT::pointer(0, 64));
109 MIRBuilder.buildFrameIndex(AddrReg, FI);
110 return AddrReg;
111 }
112
113 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
114 CCValAssign &VA) override {
115 markPhysRegUsed(PhysReg);
116 MIRBuilder.buildCopy(ValVReg, PhysReg);
117 // FIXME: assert extension
118 }
119
120 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
121 MachinePointerInfo &MPO, CCValAssign &VA) override {
122 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
123 MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size,
124 0);
125 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
126 }
127
128 /// How the physical register gets marked varies between formal
129 /// parameters (it's a basic-block live-in), and a call instruction
130 /// (it's an implicit-def of the BL).
131 virtual void markPhysRegUsed(unsigned PhysReg) = 0;
132};
133
134struct FormalArgHandler : public IncomingArgHandler {
135 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
136 : IncomingArgHandler(MIRBuilder, MRI) {}
137
138 void markPhysRegUsed(unsigned PhysReg) override {
139 MIRBuilder.getMBB().addLiveIn(PhysReg);
140 }
141};
142
143struct CallReturnHandler : public IncomingArgHandler {
144 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
145 MachineInstrBuilder MIB)
146 : IncomingArgHandler(MIRBuilder, MRI), MIB(MIB) {}
147
148 void markPhysRegUsed(unsigned PhysReg) override {
149 MIB.addDef(PhysReg, RegState::Implicit);
150 }
151
152 MachineInstrBuilder MIB;
153};
154
155struct OutgoingArgHandler : public AArch64CallLowering::ValueHandler {
156 OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
157 MachineInstrBuilder MIB)
158 : ValueHandler(MIRBuilder, MRI), MIB(MIB) {}
159
160 unsigned getStackAddress(uint64_t Size, int64_t Offset,
161 MachinePointerInfo &MPO) override {
162 LLT p0 = LLT::pointer(0, 64);
163 LLT s64 = LLT::scalar(64);
164 unsigned SPReg = MRI.createGenericVirtualRegister(p0);
165 MIRBuilder.buildCopy(SPReg, AArch64::SP);
166
167 unsigned OffsetReg = MRI.createGenericVirtualRegister(s64);
168 MIRBuilder.buildConstant(OffsetReg, Offset);
169
170 unsigned AddrReg = MRI.createGenericVirtualRegister(p0);
171 MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
172
173 MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
174 return AddrReg;
175 }
176
177 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
178 CCValAssign &VA) override {
179 MIB.addUse(PhysReg, RegState::Implicit);
180 unsigned ExtReg = extendRegister(ValVReg, VA);
181 MIRBuilder.buildCopy(PhysReg, ExtReg);
182 }
183
184 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
185 MachinePointerInfo &MPO, CCValAssign &VA) override {
186 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
187 MPO, MachineMemOperand::MOStore, Size, 0);
188 MIRBuilder.buildStore(ValVReg, Addr, *MMO);
189 }
190
191 MachineInstrBuilder MIB;
192};
193
Tim Northover9a467182016-09-21 12:57:45 +0000194void AArch64CallLowering::splitToValueTypes(const ArgInfo &OrigArg,
195 SmallVectorImpl<ArgInfo> &SplitArgs,
196 const DataLayout &DL,
197 MachineRegisterInfo &MRI,
198 SplitArgTy PerformArgSplit) const {
Tim Northoverb18ea162016-09-20 15:20:36 +0000199 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
Tim Northover9a467182016-09-21 12:57:45 +0000200 LLVMContext &Ctx = OrigArg.Ty->getContext();
Tim Northoverb18ea162016-09-20 15:20:36 +0000201
202 SmallVector<EVT, 4> SplitVTs;
203 SmallVector<uint64_t, 4> Offsets;
Tim Northover9a467182016-09-21 12:57:45 +0000204 ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
Tim Northoverb18ea162016-09-20 15:20:36 +0000205
206 if (SplitVTs.size() == 1) {
207 // No splitting to do, just forward the input directly.
Tim Northover9a467182016-09-21 12:57:45 +0000208 SplitArgs.push_back(OrigArg);
Tim Northoverb18ea162016-09-20 15:20:36 +0000209 return;
210 }
211
Tim Northover9a467182016-09-21 12:57:45 +0000212 unsigned FirstRegIdx = SplitArgs.size();
Tim Northoverb18ea162016-09-20 15:20:36 +0000213 for (auto SplitVT : SplitVTs) {
Tim Northover9a467182016-09-21 12:57:45 +0000214 // FIXME: set split flags if they're actually used (e.g. i128 on AAPCS).
Tim Northoverb18ea162016-09-20 15:20:36 +0000215 Type *SplitTy = SplitVT.getTypeForEVT(Ctx);
Tim Northover9a467182016-09-21 12:57:45 +0000216 SplitArgs.push_back(
217 ArgInfo{MRI.createGenericVirtualRegister(LLT{*SplitTy, DL}), SplitTy,
218 OrigArg.Flags});
Tim Northoverb18ea162016-09-20 15:20:36 +0000219 }
220
221 SmallVector<uint64_t, 4> BitOffsets;
222 for (auto Offset : Offsets)
223 BitOffsets.push_back(Offset * 8);
224
Tim Northover9a467182016-09-21 12:57:45 +0000225 SmallVector<unsigned, 8> SplitRegs;
226 for (auto I = &SplitArgs[FirstRegIdx]; I != SplitArgs.end(); ++I)
227 SplitRegs.push_back(I->Reg);
228
229 PerformArgSplit(SplitRegs, BitOffsets);
Tim Northoverb18ea162016-09-20 15:20:36 +0000230}
231
232bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
233 const Value *Val, unsigned VReg) const {
234 MachineFunction &MF = MIRBuilder.getMF();
235 const Function &F = *MF.getFunction();
236
237 MachineInstrBuilder MIB = MIRBuilder.buildInstr(AArch64::RET_ReallyLR);
238 assert(MIB.getInstr() && "Unable to build a return instruction?!");
239
240 assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg");
241 if (VReg) {
242 MIRBuilder.setInstr(*MIB.getInstr(), /* Before */ true);
243 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
244 CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
245 MachineRegisterInfo &MRI = MF.getRegInfo();
246 auto &DL = F.getParent()->getDataLayout();
247
Tim Northover9a467182016-09-21 12:57:45 +0000248 ArgInfo OrigArg{VReg, Val->getType()};
249 setArgFlags(OrigArg, AttributeSet::ReturnIndex, DL, F);
250
251 SmallVector<ArgInfo, 8> SplitArgs;
252 splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
Tim Northoverb18ea162016-09-20 15:20:36 +0000253 [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) {
254 MIRBuilder.buildExtract(Regs, Offsets, VReg);
255 });
256
Tim Northovera5e38fa2016-09-22 13:49:25 +0000257 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB);
258 return handleAssignments(MIRBuilder, AssignFn, SplitArgs, Handler);
Tim Northoverb18ea162016-09-20 15:20:36 +0000259 }
260 return true;
261}
262
Tim Northover862758ec2016-09-21 12:57:35 +0000263bool AArch64CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
264 const Function &F,
265 ArrayRef<unsigned> VRegs) const {
266 auto &Args = F.getArgumentList();
Tim Northover406024a2016-08-10 21:44:01 +0000267 MachineFunction &MF = MIRBuilder.getMF();
Tim Northoverb18ea162016-09-20 15:20:36 +0000268 MachineBasicBlock &MBB = MIRBuilder.getMBB();
269 MachineRegisterInfo &MRI = MF.getRegInfo();
Tim Northoverb18ea162016-09-20 15:20:36 +0000270 auto &DL = F.getParent()->getDataLayout();
Tim Northover406024a2016-08-10 21:44:01 +0000271
Tim Northover9a467182016-09-21 12:57:45 +0000272 SmallVector<ArgInfo, 8> SplitArgs;
Tim Northoverb18ea162016-09-20 15:20:36 +0000273 unsigned i = 0;
274 for (auto &Arg : Args) {
Tim Northover9a467182016-09-21 12:57:45 +0000275 ArgInfo OrigArg{VRegs[i], Arg.getType()};
276 setArgFlags(OrigArg, i + 1, DL, F);
277 splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
Tim Northoverb18ea162016-09-20 15:20:36 +0000278 [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) {
279 MIRBuilder.buildSequence(VRegs[i], Regs, Offsets);
280 });
281 ++i;
282 }
283
284 if (!MBB.empty())
285 MIRBuilder.setInstr(*MBB.begin());
Tim Northover406024a2016-08-10 21:44:01 +0000286
287 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
288 CCAssignFn *AssignFn =
289 TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/false);
290
Tim Northovera5e38fa2016-09-22 13:49:25 +0000291 FormalArgHandler Handler(MIRBuilder, MRI);
292 if (!handleAssignments(MIRBuilder, AssignFn, SplitArgs, Handler))
Tim Northover9a467182016-09-21 12:57:45 +0000293 return false;
Tim Northoverb18ea162016-09-20 15:20:36 +0000294
295 // Move back to the end of the basic block.
296 MIRBuilder.setMBB(MBB);
297
Tim Northover9a467182016-09-21 12:57:45 +0000298 return true;
Tim Northover406024a2016-08-10 21:44:01 +0000299}
300
301bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
Tim Northover9a467182016-09-21 12:57:45 +0000302 const MachineOperand &Callee,
303 const ArgInfo &OrigRet,
304 ArrayRef<ArgInfo> OrigArgs) const {
Tim Northover406024a2016-08-10 21:44:01 +0000305 MachineFunction &MF = MIRBuilder.getMF();
306 const Function &F = *MF.getFunction();
Tim Northoverb18ea162016-09-20 15:20:36 +0000307 MachineRegisterInfo &MRI = MF.getRegInfo();
308 auto &DL = F.getParent()->getDataLayout();
309
Tim Northover9a467182016-09-21 12:57:45 +0000310 SmallVector<ArgInfo, 8> SplitArgs;
311 for (auto &OrigArg : OrigArgs) {
312 splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
Tim Northoverb18ea162016-09-20 15:20:36 +0000313 [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) {
Tim Northover9a467182016-09-21 12:57:45 +0000314 MIRBuilder.buildExtract(Regs, Offsets, OrigArg.Reg);
Tim Northoverb18ea162016-09-20 15:20:36 +0000315 });
316 }
Tim Northover406024a2016-08-10 21:44:01 +0000317
Tim Northover406024a2016-08-10 21:44:01 +0000318 // Find out which ABI gets to decide where things go.
319 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
320 CCAssignFn *CallAssignFn =
321 TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/false);
322
Tim Northovera5e38fa2016-09-22 13:49:25 +0000323 // Create a temporarily-floating call instruction so we can add the implicit
324 // uses of arg registers.
325 auto MIB = MIRBuilder.buildInstrNoInsert(Callee.isReg() ? AArch64::BLR
326 : AArch64::BL);
Tim Northoverfe5f89b2016-08-29 19:07:08 +0000327 MIB.addOperand(Callee);
Tim Northover406024a2016-08-10 21:44:01 +0000328
329 // Tell the call which registers are clobbered.
330 auto TRI = MF.getSubtarget().getRegisterInfo();
331 MIB.addRegMask(TRI->getCallPreservedMask(MF, F.getCallingConv()));
332
Tim Northovera5e38fa2016-09-22 13:49:25 +0000333 // Do the actual argument marshalling.
334 SmallVector<unsigned, 8> PhysRegs;
335 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB);
336 if (!handleAssignments(MIRBuilder, CallAssignFn, SplitArgs, Handler))
337 return false;
338
339 // Now we can add the actual call instruction to the correct basic block.
340 MIRBuilder.insertInstr(MIB);
Tim Northover406024a2016-08-10 21:44:01 +0000341
342 // Finally we can copy the returned value back into its virtual-register. In
343 // symmetry with the arugments, the physical register must be an
344 // implicit-define of the call instruction.
345 CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
Tim Northover9a467182016-09-21 12:57:45 +0000346 if (OrigRet.Reg) {
347 SplitArgs.clear();
Tim Northoverb18ea162016-09-20 15:20:36 +0000348
349 SmallVector<uint64_t, 8> RegOffsets;
Tim Northover9a467182016-09-21 12:57:45 +0000350 SmallVector<unsigned, 8> SplitRegs;
351 splitToValueTypes(OrigRet, SplitArgs, DL, MRI,
Tim Northoverb18ea162016-09-20 15:20:36 +0000352 [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) {
353 std::copy(Offsets.begin(), Offsets.end(),
354 std::back_inserter(RegOffsets));
Tim Northover9a467182016-09-21 12:57:45 +0000355 std::copy(Regs.begin(), Regs.end(),
356 std::back_inserter(SplitRegs));
Tim Northoverb18ea162016-09-20 15:20:36 +0000357 });
358
Tim Northovera5e38fa2016-09-22 13:49:25 +0000359 CallReturnHandler Handler(MIRBuilder, MRI, MIB);
360 if (!handleAssignments(MIRBuilder, RetAssignFn, SplitArgs, Handler))
Tim Northover9a467182016-09-21 12:57:45 +0000361 return false;
Tim Northover406024a2016-08-10 21:44:01 +0000362
Tim Northoverb18ea162016-09-20 15:20:36 +0000363 if (!RegOffsets.empty())
Tim Northover9a467182016-09-21 12:57:45 +0000364 MIRBuilder.buildSequence(OrigRet.Reg, SplitRegs, RegOffsets);
Tim Northoverb18ea162016-09-20 15:20:36 +0000365 }
366
Tim Northover406024a2016-08-10 21:44:01 +0000367 return true;
368}