blob: 6e318139f3665455d9e0a5dc7729962661a8ddae [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
Quentin Colombetba2a0162016-02-16 19:26:02 +000035
Tim Northover406024a2016-08-10 21:44:01 +000036bool AArch64CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder,
37 CCAssignFn *AssignFn,
Tim Northover11a23542016-08-31 21:24:02 +000038 ArrayRef<Type *> ArgTypes,
Tim Northover406024a2016-08-10 21:44:01 +000039 ArrayRef<unsigned> ArgRegs,
40 AssignFnTy AssignValToReg) const {
Quentin Colombetba2a0162016-02-16 19:26:02 +000041 MachineFunction &MF = MIRBuilder.getMF();
42 const Function &F = *MF.getFunction();
43
44 SmallVector<CCValAssign, 16> ArgLocs;
45 CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
46
Tim Northover406024a2016-08-10 21:44:01 +000047 unsigned NumArgs = ArgTypes.size();
Tim Northover11a23542016-08-31 21:24:02 +000048 auto CurTy = ArgTypes.begin();
49 for (unsigned i = 0; i != NumArgs; ++i, ++CurTy) {
50 MVT CurVT = MVT::getVT(*CurTy);
51 if (AssignFn(i, CurVT, CurVT, CCValAssign::Full, ISD::ArgFlagsTy(), CCInfo))
Quentin Colombeta94caa52016-08-27 00:18:28 +000052 return false;
Quentin Colombetba2a0162016-02-16 19:26:02 +000053 }
Tim Northover406024a2016-08-10 21:44:01 +000054 assert(ArgLocs.size() == ArgTypes.size() &&
Quentin Colombetba2a0162016-02-16 19:26:02 +000055 "We have a different number of location and args?!");
56 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
57 CCValAssign &VA = ArgLocs[i];
58
Quentin Colombeta94caa52016-08-27 00:18:28 +000059 // FIXME: Support non-register argument.
60 if (!VA.isRegLoc())
61 return false;
Quentin Colombetba2a0162016-02-16 19:26:02 +000062
63 switch (VA.getLocInfo()) {
64 default:
Quentin Colombeta94caa52016-08-27 00:18:28 +000065 // Unknown loc info!
66 return false;
Quentin Colombetba2a0162016-02-16 19:26:02 +000067 case CCValAssign::Full:
68 break;
69 case CCValAssign::BCvt:
70 // We don't care about bitcast.
71 break;
72 case CCValAssign::AExt:
Tim Northover97d0cb32016-08-05 17:16:40 +000073 // Existing high bits are fine for anyext (whatever they are).
74 break;
Quentin Colombetba2a0162016-02-16 19:26:02 +000075 case CCValAssign::SExt:
76 case CCValAssign::ZExt:
77 // Zero/Sign extend the register.
Quentin Colombeta94caa52016-08-27 00:18:28 +000078 // FIXME: Not yet implemented
79 return false;
Quentin Colombetba2a0162016-02-16 19:26:02 +000080 }
Tim Northover406024a2016-08-10 21:44:01 +000081
82 // Everything checks out, tell the caller where we've decided this
83 // parameter/return value should go.
Tim Northover11a23542016-08-31 21:24:02 +000084 AssignValToReg(MIRBuilder, ArgTypes[i], ArgRegs[i], VA.getLocReg());
Quentin Colombetba2a0162016-02-16 19:26:02 +000085 }
86 return true;
87}
Tim Northover406024a2016-08-10 21:44:01 +000088
Tim Northoverb18ea162016-09-20 15:20:36 +000089void AArch64CallLowering::splitToValueTypes(
90 unsigned Reg, Type *Ty, SmallVectorImpl<unsigned> &SplitRegs,
91 SmallVectorImpl<Type *> &SplitTys, const DataLayout &DL,
92 MachineRegisterInfo &MRI, SplitArgTy SplitArg) const {
93 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
94 LLVMContext &Ctx = Ty->getContext();
95
96 SmallVector<EVT, 4> SplitVTs;
97 SmallVector<uint64_t, 4> Offsets;
98 ComputeValueVTs(TLI, DL, Ty, SplitVTs, &Offsets, 0);
99
100 if (SplitVTs.size() == 1) {
101 // No splitting to do, just forward the input directly.
102 SplitTys.push_back(Ty);
103 SplitRegs.push_back(Reg);
104 return;
105 }
106
107 unsigned FirstRegIdx = SplitRegs.size();
108 for (auto SplitVT : SplitVTs) {
109 Type *SplitTy = SplitVT.getTypeForEVT(Ctx);
110 SplitRegs.push_back(MRI.createGenericVirtualRegister(LLT{*SplitTy, DL}));
111 SplitTys.push_back(SplitTy);
112 }
113
114 SmallVector<uint64_t, 4> BitOffsets;
115 for (auto Offset : Offsets)
116 BitOffsets.push_back(Offset * 8);
117
118 SplitArg(ArrayRef<unsigned>(&SplitRegs[FirstRegIdx], SplitRegs.end()),
119 BitOffsets);
120}
121
122bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
123 const Value *Val, unsigned VReg) const {
124 MachineFunction &MF = MIRBuilder.getMF();
125 const Function &F = *MF.getFunction();
126
127 MachineInstrBuilder MIB = MIRBuilder.buildInstr(AArch64::RET_ReallyLR);
128 assert(MIB.getInstr() && "Unable to build a return instruction?!");
129
130 assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg");
131 if (VReg) {
132 MIRBuilder.setInstr(*MIB.getInstr(), /* Before */ true);
133 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
134 CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
135 MachineRegisterInfo &MRI = MF.getRegInfo();
136 auto &DL = F.getParent()->getDataLayout();
137
138 SmallVector<Type *, 8> SplitTys;
139 SmallVector<unsigned, 8> SplitRegs;
140 splitToValueTypes(VReg, Val->getType(), SplitRegs, SplitTys, DL, MRI,
141 [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) {
142 MIRBuilder.buildExtract(Regs, Offsets, VReg);
143 });
144
145 return handleAssignments(MIRBuilder, AssignFn, SplitTys, SplitRegs,
146 [&](MachineIRBuilder &MIRBuilder, Type *Ty,
147 unsigned ValReg, unsigned PhysReg) {
148 MIRBuilder.buildCopy(PhysReg, ValReg);
149 MIB.addUse(PhysReg, RegState::Implicit);
150 });
151 }
152 return true;
153}
154
Tim Northover406024a2016-08-10 21:44:01 +0000155bool AArch64CallLowering::lowerFormalArguments(
156 MachineIRBuilder &MIRBuilder, const Function::ArgumentListType &Args,
157 ArrayRef<unsigned> VRegs) const {
158 MachineFunction &MF = MIRBuilder.getMF();
Tim Northoverb18ea162016-09-20 15:20:36 +0000159 MachineBasicBlock &MBB = MIRBuilder.getMBB();
160 MachineRegisterInfo &MRI = MF.getRegInfo();
Tim Northover406024a2016-08-10 21:44:01 +0000161 const Function &F = *MF.getFunction();
Tim Northoverb18ea162016-09-20 15:20:36 +0000162 auto &DL = F.getParent()->getDataLayout();
Tim Northover406024a2016-08-10 21:44:01 +0000163
Tim Northoverb18ea162016-09-20 15:20:36 +0000164 SmallVector<MachineInstr *, 8> Seqs;
165 SmallVector<Type *, 8> SplitTys;
166 SmallVector<unsigned, 8> SplitRegs;
167 unsigned i = 0;
168 for (auto &Arg : Args) {
169 splitToValueTypes(VRegs[i], Arg.getType(), SplitRegs, SplitTys, DL, MRI,
170 [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) {
171 MIRBuilder.buildSequence(VRegs[i], Regs, Offsets);
172 });
173 ++i;
174 }
175
176 if (!MBB.empty())
177 MIRBuilder.setInstr(*MBB.begin());
Tim Northover406024a2016-08-10 21:44:01 +0000178
179 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
180 CCAssignFn *AssignFn =
181 TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/false);
182
Tim Northoverb18ea162016-09-20 15:20:36 +0000183 bool Res = handleAssignments(MIRBuilder, AssignFn, SplitTys, SplitRegs,
184 [](MachineIRBuilder &MIRBuilder, Type *Ty,
185 unsigned ValReg, unsigned PhysReg) {
186 MIRBuilder.getMBB().addLiveIn(PhysReg);
187 MIRBuilder.buildCopy(ValReg, PhysReg);
188 });
189
190 // Move back to the end of the basic block.
191 MIRBuilder.setMBB(MBB);
192
193 return Res;
Tim Northover406024a2016-08-10 21:44:01 +0000194}
195
196bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
Tim Northoverb18ea162016-09-20 15:20:36 +0000197 const MachineOperand &Callee, Type *ResTy,
198 unsigned ResReg, ArrayRef<Type *> ArgTys,
Tim Northover406024a2016-08-10 21:44:01 +0000199 ArrayRef<unsigned> ArgRegs) const {
200 MachineFunction &MF = MIRBuilder.getMF();
201 const Function &F = *MF.getFunction();
Tim Northoverb18ea162016-09-20 15:20:36 +0000202 MachineRegisterInfo &MRI = MF.getRegInfo();
203 auto &DL = F.getParent()->getDataLayout();
204
205 SmallVector<Type *, 8> SplitTys;
206 SmallVector<unsigned, 8> SplitRegs;
207 for (unsigned i = 0; i < ArgTys.size(); ++i) {
208 splitToValueTypes(ArgRegs[i], ArgTys[i], SplitRegs, SplitTys, DL, MRI,
209 [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) {
210 MIRBuilder.buildExtract(Regs, Offsets, ArgRegs[i]);
211 });
212 }
Tim Northover406024a2016-08-10 21:44:01 +0000213
Tim Northover406024a2016-08-10 21:44:01 +0000214 // Find out which ABI gets to decide where things go.
215 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
216 CCAssignFn *CallAssignFn =
217 TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/false);
218
219 // And finally we can do the actual assignments. For a call we need to keep
220 // track of the registers used because they'll be implicit uses of the BL.
221 SmallVector<unsigned, 8> PhysRegs;
Tim Northoverb18ea162016-09-20 15:20:36 +0000222 handleAssignments(MIRBuilder, CallAssignFn, SplitTys, SplitRegs,
Tim Northover11a23542016-08-31 21:24:02 +0000223 [&](MachineIRBuilder &MIRBuilder, Type *Ty, unsigned ValReg,
224 unsigned PhysReg) {
225 MIRBuilder.buildCopy(PhysReg, ValReg);
226 PhysRegs.push_back(PhysReg);
227 });
Tim Northover406024a2016-08-10 21:44:01 +0000228
229 // Now we can build the actual call instruction.
Tim Northoverfe5f89b2016-08-29 19:07:08 +0000230 auto MIB = MIRBuilder.buildInstr(Callee.isReg() ? AArch64::BLR : AArch64::BL);
231 MIB.addOperand(Callee);
Tim Northover406024a2016-08-10 21:44:01 +0000232
233 // Tell the call which registers are clobbered.
234 auto TRI = MF.getSubtarget().getRegisterInfo();
235 MIB.addRegMask(TRI->getCallPreservedMask(MF, F.getCallingConv()));
236
237 for (auto Reg : PhysRegs)
238 MIB.addUse(Reg, RegState::Implicit);
239
240 // Finally we can copy the returned value back into its virtual-register. In
241 // symmetry with the arugments, the physical register must be an
242 // implicit-define of the call instruction.
243 CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
Tim Northoverb18ea162016-09-20 15:20:36 +0000244 if (ResReg) {
245 SplitTys.clear();
246 SplitRegs.clear();
247
248 SmallVector<uint64_t, 8> RegOffsets;
249 splitToValueTypes(ResReg, ResTy, SplitRegs, SplitTys, DL, MRI,
250 [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) {
251 std::copy(Offsets.begin(), Offsets.end(),
252 std::back_inserter(RegOffsets));
253 });
254
255 handleAssignments(MIRBuilder, RetAssignFn, SplitTys, SplitRegs,
Tim Northover11a23542016-08-31 21:24:02 +0000256 [&](MachineIRBuilder &MIRBuilder, Type *Ty,
257 unsigned ValReg, unsigned PhysReg) {
Tim Northover0f140c72016-09-09 11:46:34 +0000258 MIRBuilder.buildCopy(ValReg, PhysReg);
Tim Northover11a23542016-08-31 21:24:02 +0000259 MIB.addDef(PhysReg, RegState::Implicit);
260 });
Tim Northover406024a2016-08-10 21:44:01 +0000261
Tim Northoverb18ea162016-09-20 15:20:36 +0000262 if (!RegOffsets.empty())
263 MIRBuilder.buildSequence(ResReg, SplitRegs, RegOffsets);
264 }
265
Tim Northover406024a2016-08-10 21:44:01 +0000266 return true;
267}