Line data Source code
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"
23 : #include "llvm/CodeGen/CallingConvLower.h"
24 : #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
25 : #include "llvm/CodeGen/GlobalISel/Utils.h"
26 : #include "llvm/CodeGen/LowLevelType.h"
27 : #include "llvm/CodeGen/MachineBasicBlock.h"
28 : #include "llvm/CodeGen/MachineFrameInfo.h"
29 : #include "llvm/CodeGen/MachineFunction.h"
30 : #include "llvm/CodeGen/MachineInstrBuilder.h"
31 : #include "llvm/CodeGen/MachineMemOperand.h"
32 : #include "llvm/CodeGen/MachineOperand.h"
33 : #include "llvm/CodeGen/MachineRegisterInfo.h"
34 : #include "llvm/CodeGen/TargetRegisterInfo.h"
35 : #include "llvm/CodeGen/TargetSubtargetInfo.h"
36 : #include "llvm/CodeGen/ValueTypes.h"
37 : #include "llvm/IR/Attributes.h"
38 : #include "llvm/IR/DataLayout.h"
39 : #include "llvm/IR/DerivedTypes.h"
40 : #include "llvm/IR/Function.h"
41 : #include "llvm/IR/Type.h"
42 : #include "llvm/IR/Value.h"
43 : #include "llvm/Support/Casting.h"
44 : #include "llvm/Support/LowLevelTypeImpl.h"
45 : #include "llvm/Support/MachineValueType.h"
46 : #include <algorithm>
47 : #include <cassert>
48 : #include <cstdint>
49 : #include <utility>
50 :
51 : using namespace llvm;
52 :
53 5050 : ARMCallLowering::ARMCallLowering(const ARMTargetLowering &TLI)
54 10100 : : CallLowering(&TLI) {}
55 :
56 1538 : static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI,
57 : Type *T) {
58 1538 : if (T->isArrayTy())
59 : return true;
60 :
61 1481 : 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 70 : for (unsigned i = 1, e = StructT->getNumElements(); i != e; ++i)
66 90 : if (StructT->getElementType(i) != StructT->getElementType(0))
67 : return false;
68 : return true;
69 : }
70 :
71 1451 : EVT VT = TLI.getValueType(DL, T, true);
72 1451 : if (!VT.isSimple() || VT.isVector() ||
73 1436 : !(VT.isInteger() || VT.isFloatingPoint()))
74 : return false;
75 :
76 1436 : unsigned VTSize = VT.getSimpleVT().getSizeInBits();
77 :
78 1436 : if (VTSize == 64)
79 : // FIXME: Support i64 too
80 299 : return VT.isFloatingPoint();
81 :
82 1137 : 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 240 : struct OutgoingValueHandler : public CallLowering::ValueHandler {
90 : OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
91 : MachineInstrBuilder &MIB, CCAssignFn *AssignFn)
92 240 : : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
93 :
94 102 : 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 102 : LLT p0 = LLT::pointer(0, 32);
100 102 : LLT s32 = LLT::scalar(32);
101 204 : unsigned SPReg = MRI.createGenericVirtualRegister(p0);
102 102 : MIRBuilder.buildCopy(SPReg, ARM::SP);
103 :
104 204 : unsigned OffsetReg = MRI.createGenericVirtualRegister(s32);
105 102 : MIRBuilder.buildConstant(OffsetReg, Offset);
106 :
107 204 : unsigned AddrReg = MRI.createGenericVirtualRegister(p0);
108 102 : MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
109 :
110 102 : MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
111 102 : return AddrReg;
112 : }
113 :
114 869 : 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 869 : unsigned ExtReg = extendRegister(ValVReg, VA);
123 869 : MIRBuilder.buildCopy(PhysReg, ExtReg);
124 869 : MIB.addUse(PhysReg, RegState::Implicit);
125 869 : }
126 :
127 102 : 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 102 : unsigned ExtReg = extendRegister(ValVReg, VA);
133 204 : auto MMO = MIRBuilder.getMF().getMachineMemOperand(
134 102 : MPO, MachineMemOperand::MOStore, VA.getLocVT().getStoreSize(),
135 : /* Alignment */ 0);
136 102 : MIRBuilder.buildStore(ExtReg, Addr, *MMO);
137 102 : }
138 :
139 145 : unsigned assignCustomValue(const CallLowering::ArgInfo &Arg,
140 : ArrayRef<CCValAssign> VAs) override {
141 145 : CCValAssign VA = VAs[0];
142 : assert(VA.needsCustom() && "Value doesn't need custom handling");
143 : assert(VA.getValVT() == MVT::f64 && "Unsupported type");
144 :
145 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 290 : unsigned NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
156 290 : MRI.createGenericVirtualRegister(LLT::scalar(32))};
157 290 : MIRBuilder.buildUnmerge(NewRegs, Arg.Reg);
158 :
159 145 : bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
160 145 : if (!IsLittle)
161 : std::swap(NewRegs[0], NewRegs[1]);
162 :
163 145 : assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
164 145 : assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
165 :
166 145 : return 1;
167 : }
168 :
169 826 : bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
170 : CCValAssign::LocInfo LocInfo,
171 : const CallLowering::ArgInfo &Info, CCState &State) override {
172 826 : if (AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State))
173 : return true;
174 :
175 826 : StackSize =
176 826 : std::max(StackSize, static_cast<uint64_t>(State.getNextStackOffset()));
177 826 : return false;
178 : }
179 :
180 : MachineInstrBuilder &MIB;
181 : uint64_t StackSize = 0;
182 : };
183 :
184 : } // end anonymous namespace
185 :
186 1509 : void ARMCallLowering::splitToValueTypes(
187 : const ArgInfo &OrigArg, SmallVectorImpl<ArgInfo> &SplitArgs,
188 : MachineFunction &MF, const SplitArgTy &PerformArgSplit) const {
189 1509 : const ARMTargetLowering &TLI = *getTLI<ARMTargetLowering>();
190 1509 : LLVMContext &Ctx = OrigArg.Ty->getContext();
191 1509 : const DataLayout &DL = MF.getDataLayout();
192 1509 : MachineRegisterInfo &MRI = MF.getRegInfo();
193 1509 : const Function &F = MF.getFunction();
194 :
195 : SmallVector<EVT, 4> SplitVTs;
196 : SmallVector<uint64_t, 4> Offsets;
197 1509 : ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
198 :
199 1509 : 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 1437 : auto Flags = OrigArg.Flags;
203 1437 : unsigned OriginalAlignment = DL.getABITypeAlignment(OrigArg.Ty);
204 : Flags.setOrigAlign(OriginalAlignment);
205 1437 : SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx), Flags,
206 1437 : OrigArg.IsFixed);
207 : return;
208 : }
209 :
210 72 : unsigned FirstRegIdx = SplitArgs.size();
211 487 : for (unsigned i = 0, e = SplitVTs.size(); i != e; ++i) {
212 415 : EVT SplitVT = SplitVTs[i];
213 415 : Type *SplitTy = SplitVT.getTypeForEVT(Ctx);
214 415 : auto Flags = OrigArg.Flags;
215 :
216 415 : unsigned OriginalAlignment = DL.getABITypeAlignment(SplitTy);
217 : Flags.setOrigAlign(OriginalAlignment);
218 :
219 : bool NeedsConsecutiveRegisters =
220 830 : TLI.functionArgumentNeedsConsecutiveRegisters(
221 415 : SplitTy, F.getCallingConv(), F.isVarArg());
222 415 : if (NeedsConsecutiveRegisters) {
223 : Flags.setInConsecutiveRegs();
224 48 : if (i == e - 1)
225 : Flags.setInConsecutiveRegsLast();
226 : }
227 :
228 415 : SplitArgs.push_back(
229 415 : ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*SplitTy, DL)),
230 415 : SplitTy, Flags, OrigArg.IsFixed});
231 : }
232 :
233 487 : for (unsigned i = 0; i < Offsets.size(); ++i)
234 1245 : 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 270 : bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
240 : const Value *Val, ArrayRef<unsigned> VRegs,
241 : MachineInstrBuilder &Ret) const {
242 270 : if (!Val)
243 : // Nothing to do here.
244 : return true;
245 :
246 254 : auto &MF = MIRBuilder.getMF();
247 254 : const auto &F = MF.getFunction();
248 :
249 508 : auto DL = MF.getDataLayout();
250 254 : auto &TLI = *getTLI<ARMTargetLowering>();
251 254 : if (!isSupportedType(DL, TLI, Val->getType()))
252 : return false;
253 :
254 : SmallVector<EVT, 4> SplitEVTs;
255 254 : ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs);
256 : assert(VRegs.size() == SplitEVTs.size() &&
257 : "For each split Type there should be exactly one VReg.");
258 :
259 : SmallVector<ArgInfo, 4> SplitVTs;
260 254 : LLVMContext &Ctx = Val->getType()->getContext();
261 524 : for (unsigned i = 0; i < SplitEVTs.size(); ++i) {
262 270 : ArgInfo CurArgInfo(VRegs[i], SplitEVTs[i].getTypeForEVT(Ctx));
263 270 : setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
264 :
265 : SmallVector<unsigned, 4> Regs;
266 270 : splitToValueTypes(
267 : CurArgInfo, SplitVTs, MF,
268 0 : [&](unsigned Reg, uint64_t Offset) { Regs.push_back(Reg); });
269 540 : if (Regs.size() > 1)
270 0 : MIRBuilder.buildUnmerge(Regs, VRegs[i]);
271 : }
272 :
273 : CCAssignFn *AssignFn =
274 508 : TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
275 :
276 254 : OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret, AssignFn);
277 508 : return handleAssignments(MIRBuilder, SplitVTs, RetHandler);
278 : }
279 :
280 270 : bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
281 : const Value *Val,
282 : ArrayRef<unsigned> VRegs) const {
283 : assert(!Val == VRegs.empty() && "Return value without a vreg");
284 :
285 270 : auto const &ST = MIRBuilder.getMF().getSubtarget<ARMSubtarget>();
286 : unsigned Opcode = ST.getReturnOpcode();
287 270 : auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL));
288 :
289 270 : if (!lowerReturnVal(MIRBuilder, Val, VRegs, Ret))
290 : return false;
291 :
292 270 : MIRBuilder.insertInstr(Ret);
293 270 : return true;
294 : }
295 :
296 : namespace {
297 :
298 : /// Helper class for values coming in through an ABI boundary (used for handling
299 : /// formal arguments and call return values).
300 : struct IncomingValueHandler : public CallLowering::ValueHandler {
301 : IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
302 : CCAssignFn AssignFn)
303 : : ValueHandler(MIRBuilder, MRI, AssignFn) {}
304 :
305 140 : unsigned getStackAddress(uint64_t Size, int64_t Offset,
306 : MachinePointerInfo &MPO) override {
307 : assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
308 : "Unsupported size");
309 :
310 140 : auto &MFI = MIRBuilder.getMF().getFrameInfo();
311 :
312 140 : int FI = MFI.CreateFixedObject(Size, Offset, true);
313 140 : MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
314 :
315 : unsigned AddrReg =
316 280 : MRI.createGenericVirtualRegister(LLT::pointer(MPO.getAddrSpace(), 32));
317 140 : MIRBuilder.buildFrameIndex(AddrReg, FI);
318 :
319 140 : return AddrReg;
320 : }
321 :
322 140 : void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
323 : MachinePointerInfo &MPO, CCValAssign &VA) override {
324 : assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
325 : "Unsupported size");
326 :
327 140 : if (VA.getLocInfo() == CCValAssign::SExt ||
328 : VA.getLocInfo() == CCValAssign::ZExt) {
329 : // If the value is zero- or sign-extended, its size becomes 4 bytes, so
330 : // that's what we should load.
331 : Size = 4;
332 : assert(MRI.getType(ValVReg).isScalar() && "Only scalars supported atm");
333 :
334 28 : auto LoadVReg = MRI.createGenericVirtualRegister(LLT::scalar(32));
335 14 : buildLoad(LoadVReg, Addr, Size, /* Alignment */ 0, MPO);
336 14 : MIRBuilder.buildTrunc(ValVReg, LoadVReg);
337 : } else {
338 : // If the value is not extended, a simple load will suffice.
339 126 : buildLoad(ValVReg, Addr, Size, /* Alignment */ 0, MPO);
340 : }
341 140 : }
342 :
343 0 : void buildLoad(unsigned Val, unsigned Addr, uint64_t Size, unsigned Alignment,
344 : MachinePointerInfo &MPO) {
345 0 : auto MMO = MIRBuilder.getMF().getMachineMemOperand(
346 : MPO, MachineMemOperand::MOLoad, Size, Alignment);
347 0 : MIRBuilder.buildLoad(Val, Addr, *MMO);
348 0 : }
349 :
350 838 : void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
351 : CCValAssign &VA) override {
352 : assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
353 : assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
354 :
355 838 : auto ValSize = VA.getValVT().getSizeInBits();
356 838 : auto LocSize = VA.getLocVT().getSizeInBits();
357 :
358 : assert(ValSize <= 64 && "Unsupported value size");
359 : assert(LocSize <= 64 && "Unsupported location size");
360 :
361 838 : markPhysRegUsed(PhysReg);
362 838 : if (ValSize == LocSize) {
363 674 : MIRBuilder.buildCopy(ValVReg, PhysReg);
364 : } else {
365 : assert(ValSize < LocSize && "Extensions not supported");
366 :
367 : // We cannot create a truncating copy, nor a trunc of a physical register.
368 : // Therefore, we need to copy the content of the physical register into a
369 : // virtual one and then truncate that.
370 : auto PhysRegToVReg =
371 328 : MRI.createGenericVirtualRegister(LLT::scalar(LocSize));
372 164 : MIRBuilder.buildCopy(PhysRegToVReg, PhysReg);
373 164 : MIRBuilder.buildTrunc(ValVReg, PhysRegToVReg);
374 : }
375 838 : }
376 :
377 72 : unsigned assignCustomValue(const ARMCallLowering::ArgInfo &Arg,
378 : ArrayRef<CCValAssign> VAs) override {
379 72 : CCValAssign VA = VAs[0];
380 : assert(VA.needsCustom() && "Value doesn't need custom handling");
381 : assert(VA.getValVT() == MVT::f64 && "Unsupported type");
382 :
383 72 : CCValAssign NextVA = VAs[1];
384 : assert(NextVA.needsCustom() && "Value doesn't need custom handling");
385 : assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
386 :
387 : assert(VA.getValNo() == NextVA.getValNo() &&
388 : "Values belong to different arguments");
389 :
390 : assert(VA.isRegLoc() && "Value should be in reg");
391 : assert(NextVA.isRegLoc() && "Value should be in reg");
392 :
393 144 : unsigned NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
394 144 : MRI.createGenericVirtualRegister(LLT::scalar(32))};
395 :
396 72 : assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
397 72 : assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
398 :
399 72 : bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
400 72 : if (!IsLittle)
401 : std::swap(NewRegs[0], NewRegs[1]);
402 :
403 144 : MIRBuilder.buildMerge(Arg.Reg, NewRegs);
404 :
405 72 : return 1;
406 : }
407 :
408 : /// Marking a physical register as used is different between formal
409 : /// parameters, where it's a basic block live-in, and call returns, where it's
410 : /// an implicit-def of the call instruction.
411 : virtual void markPhysRegUsed(unsigned PhysReg) = 0;
412 : };
413 :
414 221 : struct FormalArgHandler : public IncomingValueHandler {
415 : FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
416 : CCAssignFn AssignFn)
417 221 : : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
418 :
419 560 : void markPhysRegUsed(unsigned PhysReg) override {
420 560 : MIRBuilder.getMBB().addLiveIn(PhysReg);
421 560 : }
422 : };
423 :
424 : } // end anonymous namespace
425 :
426 341 : bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
427 : const Function &F,
428 : ArrayRef<unsigned> VRegs) const {
429 341 : auto &TLI = *getTLI<ARMTargetLowering>();
430 341 : auto Subtarget = TLI.getSubtarget();
431 :
432 341 : if (Subtarget->isThumb())
433 : return false;
434 :
435 : // Quick exit if there aren't any args
436 336 : if (F.arg_empty())
437 : return true;
438 :
439 261 : if (F.isVarArg())
440 : return false;
441 :
442 256 : auto &MF = MIRBuilder.getMF();
443 256 : auto &MBB = MIRBuilder.getMBB();
444 512 : auto DL = MF.getDataLayout();
445 :
446 816 : for (auto &Arg : F.args()) {
447 595 : if (!isSupportedType(DL, TLI, Arg.getType()))
448 : return false;
449 565 : if (Arg.hasByValOrInAllocaAttr())
450 : return false;
451 : }
452 :
453 : CCAssignFn *AssignFn =
454 442 : TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
455 :
456 221 : FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo(),
457 221 : AssignFn);
458 :
459 : SmallVector<ArgInfo, 8> ArgInfos;
460 : SmallVector<unsigned, 4> SplitRegs;
461 : unsigned Idx = 0;
462 781 : for (auto &Arg : F.args()) {
463 1120 : ArgInfo AInfo(VRegs[Idx], Arg.getType());
464 560 : setArgFlags(AInfo, Idx + AttributeList::FirstArgIndex, DL, F);
465 :
466 : SplitRegs.clear();
467 :
468 560 : splitToValueTypes(AInfo, ArgInfos, MF, [&](unsigned Reg, uint64_t Offset) {
469 130 : SplitRegs.push_back(Reg);
470 : });
471 :
472 560 : if (!SplitRegs.empty())
473 40 : MIRBuilder.buildMerge(VRegs[Idx], SplitRegs);
474 :
475 : Idx++;
476 : }
477 :
478 221 : if (!MBB.empty())
479 28 : MIRBuilder.setInstr(*MBB.begin());
480 :
481 442 : if (!handleAssignments(MIRBuilder, ArgInfos, ArgHandler))
482 : return false;
483 :
484 : // Move back to the end of the basic block.
485 216 : MIRBuilder.setMBB(MBB);
486 216 : return true;
487 : }
488 :
489 : namespace {
490 :
491 228 : struct CallReturnHandler : public IncomingValueHandler {
492 : CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
493 : MachineInstrBuilder MIB, CCAssignFn *AssignFn)
494 456 : : IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
495 :
496 278 : void markPhysRegUsed(unsigned PhysReg) override {
497 278 : MIB.addDef(PhysReg, RegState::Implicit);
498 278 : }
499 :
500 : MachineInstrBuilder MIB;
501 : };
502 :
503 : } // end anonymous namespace
504 :
505 250 : bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
506 : CallingConv::ID CallConv,
507 : const MachineOperand &Callee,
508 : const ArgInfo &OrigRet,
509 : ArrayRef<ArgInfo> OrigArgs) const {
510 250 : MachineFunction &MF = MIRBuilder.getMF();
511 250 : const auto &TLI = *getTLI<ARMTargetLowering>();
512 250 : const auto &DL = MF.getDataLayout();
513 250 : const auto &STI = MF.getSubtarget<ARMSubtarget>();
514 250 : const TargetRegisterInfo *TRI = STI.getRegisterInfo();
515 250 : MachineRegisterInfo &MRI = MF.getRegInfo();
516 :
517 250 : if (STI.genLongCalls())
518 : return false;
519 :
520 250 : auto CallSeqStart = MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN);
521 :
522 : // Create the call instruction so we can add the implicit uses of arg
523 : // registers, but don't insert it yet.
524 : bool isDirect = !Callee.isReg();
525 : auto CallOpcode =
526 250 : isDirect ? ARM::BL
527 3 : : STI.hasV5TOps()
528 3 : ? ARM::BLX
529 2 : : STI.hasV4TOps() ? ARM::BX_CALL : ARM::BMOVPCRX_CALL;
530 250 : auto MIB = MIRBuilder.buildInstrNoInsert(CallOpcode)
531 : .add(Callee)
532 500 : .addRegMask(TRI->getCallPreservedMask(MF, CallConv));
533 250 : if (Callee.isReg()) {
534 3 : auto CalleeReg = Callee.getReg();
535 3 : if (CalleeReg && !TRI->isPhysicalRegister(CalleeReg))
536 3 : MIB->getOperand(0).setReg(constrainOperandRegClass(
537 3 : MF, *TRI, MRI, *STI.getInstrInfo(), *STI.getRegBankInfo(),
538 : *MIB.getInstr(), MIB->getDesc(), Callee, 0));
539 : }
540 :
541 : SmallVector<ArgInfo, 8> ArgInfos;
542 701 : for (auto Arg : OrigArgs) {
543 461 : if (!isSupportedType(DL, TLI, Arg.Ty))
544 10 : return false;
545 :
546 461 : if (!Arg.IsFixed)
547 : return false;
548 :
549 456 : if (Arg.Flags.isByVal())
550 : return false;
551 :
552 : SmallVector<unsigned, 8> Regs;
553 451 : splitToValueTypes(Arg, ArgInfos, MF, [&](unsigned Reg, uint64_t Offset) {
554 130 : Regs.push_back(Reg);
555 : });
556 :
557 902 : if (Regs.size() > 1)
558 40 : MIRBuilder.buildUnmerge(Regs, Arg.Reg);
559 : }
560 :
561 240 : auto ArgAssignFn = TLI.CCAssignFnForCall(CallConv, /*IsVarArg=*/false);
562 : OutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB, ArgAssignFn);
563 480 : if (!handleAssignments(MIRBuilder, ArgInfos, ArgHandler))
564 : return false;
565 :
566 : // Now we can add the actual call instruction to the correct basic block.
567 240 : MIRBuilder.insertInstr(MIB);
568 :
569 480 : if (!OrigRet.Ty->isVoidTy()) {
570 228 : if (!isSupportedType(DL, TLI, OrigRet.Ty))
571 10 : return false;
572 :
573 : ArgInfos.clear();
574 : SmallVector<unsigned, 8> SplitRegs;
575 228 : splitToValueTypes(OrigRet, ArgInfos, MF,
576 : [&](unsigned Reg, uint64_t Offset) {
577 155 : SplitRegs.push_back(Reg);
578 : });
579 :
580 228 : auto RetAssignFn = TLI.CCAssignFnForReturn(CallConv, /*IsVarArg=*/false);
581 : CallReturnHandler RetHandler(MIRBuilder, MRI, MIB, RetAssignFn);
582 228 : if (!handleAssignments(MIRBuilder, ArgInfos, RetHandler))
583 : return false;
584 :
585 218 : if (!SplitRegs.empty()) {
586 : // We have split the value and allocated each individual piece, now build
587 : // it up again.
588 22 : MIRBuilder.buildMerge(OrigRet.Reg, SplitRegs);
589 : }
590 : }
591 :
592 : // We now know the size of the stack - update the ADJCALLSTACKDOWN
593 : // accordingly.
594 230 : CallSeqStart.addImm(ArgHandler.StackSize).addImm(0).add(predOps(ARMCC::AL));
595 :
596 230 : MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP)
597 230 : .addImm(ArgHandler.StackSize)
598 : .addImm(0)
599 230 : .add(predOps(ARMCC::AL));
600 :
601 230 : return true;
602 : }
|