Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- AArch64CallLowering.cpp - Call lowering --------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// This file implements the lowering of LLVM calls to machine code calls for
11
/// GlobalISel.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#include "AArch64CallLowering.h"
16
#include "AArch64ISelLowering.h"
17
#include "AArch64MachineFunctionInfo.h"
18
#include "AArch64Subtarget.h"
19
#include "llvm/ADT/ArrayRef.h"
20
#include "llvm/ADT/SmallVector.h"
21
#include "llvm/CodeGen/Analysis.h"
22
#include "llvm/CodeGen/CallingConvLower.h"
23
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
24
#include "llvm/CodeGen/GlobalISel/Utils.h"
25
#include "llvm/CodeGen/LowLevelType.h"
26
#include "llvm/CodeGen/MachineBasicBlock.h"
27
#include "llvm/CodeGen/MachineFrameInfo.h"
28
#include "llvm/CodeGen/MachineFunction.h"
29
#include "llvm/CodeGen/MachineInstrBuilder.h"
30
#include "llvm/CodeGen/MachineMemOperand.h"
31
#include "llvm/CodeGen/MachineOperand.h"
32
#include "llvm/CodeGen/MachineRegisterInfo.h"
33
#include "llvm/CodeGen/TargetRegisterInfo.h"
34
#include "llvm/CodeGen/TargetSubtargetInfo.h"
35
#include "llvm/CodeGen/ValueTypes.h"
36
#include "llvm/IR/Argument.h"
37
#include "llvm/IR/Attributes.h"
38
#include "llvm/IR/Function.h"
39
#include "llvm/IR/Type.h"
40
#include "llvm/IR/Value.h"
41
#include "llvm/Support/MachineValueType.h"
42
#include <algorithm>
43
#include <cassert>
44
#include <cstdint>
45
#include <iterator>
46
47
#define DEBUG_TYPE "aarch64-call-lowering"
48
49
using namespace llvm;
50
51
AArch64CallLowering::AArch64CallLowering(const AArch64TargetLowering &TLI)
52
9.10k
  : CallLowering(&TLI) {}
53
54
namespace {
55
struct IncomingArgHandler : public CallLowering::ValueHandler {
56
  IncomingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
57
                     CCAssignFn *AssignFn)
58
1.08M
      : ValueHandler(MIRBuilder, MRI, AssignFn), StackUsed(0) {}
59
60
  Register getStackAddress(uint64_t Size, int64_t Offset,
61
17.8k
                           MachinePointerInfo &MPO) override {
62
17.8k
    auto &MFI = MIRBuilder.getMF().getFrameInfo();
63
17.8k
    int FI = MFI.CreateFixedObject(Size, Offset, true);
64
17.8k
    MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
65
17.8k
    Register AddrReg = MRI.createGenericVirtualRegister(LLT::pointer(0, 64));
66
17.8k
    MIRBuilder.buildFrameIndex(AddrReg, FI);
67
17.8k
    StackUsed = std::max(StackUsed, Size + Offset);
68
17.8k
    return AddrReg;
69
17.8k
  }
70
71
  void assignValueToReg(Register ValVReg, Register PhysReg,
72
1.39M
                        CCValAssign &VA) override {
73
1.39M
    markPhysRegUsed(PhysReg);
74
1.39M
    switch (VA.getLocInfo()) {
75
1.39M
    default:
76
1.36M
      MIRBuilder.buildCopy(ValVReg, PhysReg);
77
1.36M
      break;
78
1.39M
    case CCValAssign::LocInfo::SExt:
79
23.9k
    case CCValAssign::LocInfo::ZExt:
80
23.9k
    case CCValAssign::LocInfo::AExt: {
81
23.9k
      auto Copy = MIRBuilder.buildCopy(LLT{VA.getLocVT()}, PhysReg);
82
23.9k
      MIRBuilder.buildTrunc(ValVReg, Copy);
83
23.9k
      break;
84
23.9k
    }
85
1.39M
    }
86
1.39M
  }
87
88
  void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size,
89
17.8k
                            MachinePointerInfo &MPO, CCValAssign &VA) override {
90
17.8k
    // FIXME: Get alignment
91
17.8k
    auto MMO = MIRBuilder.getMF().getMachineMemOperand(
92
17.8k
        MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size,
93
17.8k
        1);
94
17.8k
    MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
95
17.8k
  }
96
97
  /// How the physical register gets marked varies between formal
98
  /// parameters (it's a basic-block live-in), and a call instruction
99
  /// (it's an implicit-def of the BL).
100
  virtual void markPhysRegUsed(unsigned PhysReg) = 0;
101
102
1.39M
  bool isArgumentHandler() const override { return true; }
103
104
  uint64_t StackUsed;
105
};
106
107
struct FormalArgHandler : public IncomingArgHandler {
108
  FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
109
                   CCAssignFn *AssignFn)
110
235k
    : IncomingArgHandler(MIRBuilder, MRI, AssignFn) {}
111
112
541k
  void markPhysRegUsed(unsigned PhysReg) override {
113
541k
    MIRBuilder.getMBB().addLiveIn(PhysReg);
114
541k
  }
115
};
116
117
struct CallReturnHandler : public IncomingArgHandler {
118
  CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
119
                    MachineInstrBuilder MIB, CCAssignFn *AssignFn)
120
847k
    : IncomingArgHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
121
122
848k
  void markPhysRegUsed(unsigned PhysReg) override {
123
848k
    MIB.addDef(PhysReg, RegState::Implicit);
124
848k
  }
125
126
  MachineInstrBuilder MIB;
127
};
128
129
struct OutgoingArgHandler : public CallLowering::ValueHandler {
130
  OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
131
                     MachineInstrBuilder MIB, CCAssignFn *AssignFn,
132
                     CCAssignFn *AssignFnVarArg)
133
      : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB),
134
1.51M
        AssignFnVarArg(AssignFnVarArg), StackSize(0) {}
135
136
  Register getStackAddress(uint64_t Size, int64_t Offset,
137
61.3k
                           MachinePointerInfo &MPO) override {
138
61.3k
    LLT p0 = LLT::pointer(0, 64);
139
61.3k
    LLT s64 = LLT::scalar(64);
140
61.3k
    Register SPReg = MRI.createGenericVirtualRegister(p0);
141
61.3k
    MIRBuilder.buildCopy(SPReg, Register(AArch64::SP));
142
61.3k
143
61.3k
    Register OffsetReg = MRI.createGenericVirtualRegister(s64);
144
61.3k
    MIRBuilder.buildConstant(OffsetReg, Offset);
145
61.3k
146
61.3k
    Register AddrReg = MRI.createGenericVirtualRegister(p0);
147
61.3k
    MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
148
61.3k
149
61.3k
    MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
150
61.3k
    return AddrReg;
151
61.3k
  }
152
153
  void assignValueToReg(Register ValVReg, Register PhysReg,
154
3.02M
                        CCValAssign &VA) override {
155
3.02M
    MIB.addUse(PhysReg, RegState::Implicit);
156
3.02M
    Register ExtReg = extendRegister(ValVReg, VA);
157
3.02M
    MIRBuilder.buildCopy(PhysReg, ExtReg);
158
3.02M
  }
159
160
  void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size,
161
61.3k
                            MachinePointerInfo &MPO, CCValAssign &VA) override {
162
61.3k
    if (VA.getLocInfo() == CCValAssign::LocInfo::AExt) {
163
15.5k
      Size = VA.getLocVT().getSizeInBits() / 8;
164
15.5k
      ValVReg = MIRBuilder.buildAnyExt(LLT::scalar(Size * 8), ValVReg)
165
15.5k
                    ->getOperand(0)
166
15.5k
                    .getReg();
167
15.5k
    }
168
61.3k
    auto MMO = MIRBuilder.getMF().getMachineMemOperand(
169
61.3k
        MPO, MachineMemOperand::MOStore, Size, 1);
170
61.3k
    MIRBuilder.buildStore(ValVReg, Addr, *MMO);
171
61.3k
  }
172
173
  bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
174
                 CCValAssign::LocInfo LocInfo,
175
                 const CallLowering::ArgInfo &Info,
176
3.08M
                 CCState &State) override {
177
3.08M
    bool Res;
178
3.08M
    if (Info.IsFixed)
179
3.04M
      Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State);
180
42.1k
    else
181
42.1k
      Res = AssignFnVarArg(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State);
182
3.08M
183
3.08M
    StackSize = State.getNextStackOffset();
184
3.08M
    return Res;
185
3.08M
  }
186
187
  MachineInstrBuilder MIB;
188
  CCAssignFn *AssignFnVarArg;
189
  uint64_t StackSize;
190
};
191
} // namespace
192
193
void AArch64CallLowering::splitToValueTypes(
194
    const ArgInfo &OrigArg, SmallVectorImpl<ArgInfo> &SplitArgs,
195
4.49M
    const DataLayout &DL, MachineRegisterInfo &MRI, CallingConv::ID CallConv) const {
196
4.49M
  const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
197
4.49M
  LLVMContext &Ctx = OrigArg.Ty->getContext();
198
4.49M
199
4.49M
  if (OrigArg.Ty->isVoidTy())
200
0
    return;
201
4.49M
202
4.49M
  SmallVector<EVT, 4> SplitVTs;
203
4.49M
  SmallVector<uint64_t, 4> Offsets;
204
4.49M
  ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
205
4.49M
206
4.49M
  if (SplitVTs.size() == 1) {
207
4.49M
    // No splitting to do, but we want to replace the original type (e.g. [1 x
208
4.49M
    // double] -> double).
209
4.49M
    SplitArgs.emplace_back(OrigArg.Regs[0], SplitVTs[0].getTypeForEVT(Ctx),
210
4.49M
                           OrigArg.Flags, OrigArg.IsFixed);
211
4.49M
    return;
212
4.49M
  }
213
1.04k
214
1.04k
  // Create one ArgInfo for each virtual register in the original ArgInfo.
215
1.04k
  assert(OrigArg.Regs.size() == SplitVTs.size() && "Regs / types mismatch");
216
1.04k
217
1.04k
  bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters(
218
1.04k
      OrigArg.Ty, CallConv, false);
219
3.50k
  for (unsigned i = 0, e = SplitVTs.size(); i < e; 
++i2.46k
) {
220
2.46k
    Type *SplitTy = SplitVTs[i].getTypeForEVT(Ctx);
221
2.46k
    SplitArgs.emplace_back(OrigArg.Regs[i], SplitTy, OrigArg.Flags,
222
2.46k
                           OrigArg.IsFixed);
223
2.46k
    if (NeedsRegBlock)
224
1.75k
      SplitArgs.back().Flags.setInConsecutiveRegs();
225
2.46k
  }
226
1.04k
227
1.04k
  SplitArgs.back().Flags.setInConsecutiveRegsLast();
228
1.04k
}
229
230
bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
231
                                      const Value *Val,
232
                                      ArrayRef<Register> VRegs,
233
342k
                                      Register SwiftErrorVReg) const {
234
342k
  auto MIB = MIRBuilder.buildInstrNoInsert(AArch64::RET_ReallyLR);
235
342k
  assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&
236
342k
         "Return value without a vreg");
237
342k
238
342k
  bool Success = true;
239
342k
  if (!VRegs.empty()) {
240
255k
    MachineFunction &MF = MIRBuilder.getMF();
241
255k
    const Function &F = MF.getFunction();
242
255k
243
255k
    MachineRegisterInfo &MRI = MF.getRegInfo();
244
255k
    const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
245
255k
    CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
246
255k
    auto &DL = F.getParent()->getDataLayout();
247
255k
    LLVMContext &Ctx = Val->getType()->getContext();
248
255k
249
255k
    SmallVector<EVT, 4> SplitEVTs;
250
255k
    ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs);
251
255k
    assert(VRegs.size() == SplitEVTs.size() &&
252
255k
           "For each split Type there should be exactly one VReg.");
253
255k
254
255k
    SmallVector<ArgInfo, 8> SplitArgs;
255
255k
    CallingConv::ID CC = F.getCallingConv();
256
255k
257
511k
    for (unsigned i = 0; i < SplitEVTs.size(); 
++i255k
) {
258
255k
      if (TLI.getNumRegistersForCallingConv(Ctx, CC, SplitEVTs[i]) > 1) {
259
14
        LLVM_DEBUG(dbgs() << "Can't handle extended arg types which need split");
260
14
        return false;
261
14
      }
262
255k
263
255k
      Register CurVReg = VRegs[i];
264
255k
      ArgInfo CurArgInfo = ArgInfo{CurVReg, SplitEVTs[i].getTypeForEVT(Ctx)};
265
255k
      setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
266
255k
267
255k
      // i1 is a special case because SDAG i1 true is naturally zero extended
268
255k
      // when widened using ANYEXT. We need to do it explicitly here.
269
255k
      if (MRI.getType(CurVReg).getSizeInBits() == 1) {
270
7.60k
        CurVReg = MIRBuilder.buildZExt(LLT::scalar(8), CurVReg).getReg(0);
271
248k
      } else {
272
248k
        // Some types will need extending as specified by the CC.
273
248k
        MVT NewVT = TLI.getRegisterTypeForCallingConv(Ctx, CC, SplitEVTs[i]);
274
248k
        if (EVT(NewVT) != SplitEVTs[i]) {
275
123
          unsigned ExtendOp = TargetOpcode::G_ANYEXT;
276
123
          if (F.getAttributes().hasAttribute(AttributeList::ReturnIndex,
277
123
                                             Attribute::SExt))
278
62
            ExtendOp = TargetOpcode::G_SEXT;
279
61
          else if (F.getAttributes().hasAttribute(AttributeList::ReturnIndex,
280
61
                                                  Attribute::ZExt))
281
50
            ExtendOp = TargetOpcode::G_ZEXT;
282
123
283
123
          LLT NewLLT(NewVT);
284
123
          LLT OldLLT(MVT::getVT(CurArgInfo.Ty));
285
123
          CurArgInfo.Ty = EVT(NewVT).getTypeForEVT(Ctx);
286
123
          // Instead of an extend, we might have a vector type which needs
287
123
          // padding with more elements, e.g. <2 x half> -> <4 x half>.
288
123
          if (NewVT.isVector()) {
289
4
            if (OldLLT.isVector()) {
290
3
              if (NewLLT.getNumElements() > OldLLT.getNumElements()) {
291
1
                // We don't handle VA types which are not exactly twice the
292
1
                // size, but can easily be done in future.
293
1
                if (NewLLT.getNumElements() != OldLLT.getNumElements() * 2) {
294
0
                  LLVM_DEBUG(dbgs() << "Outgoing vector ret has too many elts");
295
0
                  return false;
296
0
                }
297
1
                auto Undef = MIRBuilder.buildUndef({OldLLT});
298
1
                CurVReg =
299
1
                    MIRBuilder.buildMerge({NewLLT}, {CurVReg, Undef.getReg(0)})
300
1
                        .getReg(0);
301
2
              } else {
302
2
                // Just do a vector extend.
303
2
                CurVReg = MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg})
304
2
                              .getReg(0);
305
2
              }
306
3
            } else 
if (1
NewLLT.getNumElements() == 21
) {
307
1
              // We need to pad a <1 x S> type to <2 x S>. Since we don't have
308
1
              // <1 x S> vector types in GISel we use a build_vector instead
309
1
              // of a vector merge/concat.
310
1
              auto Undef = MIRBuilder.buildUndef({OldLLT});
311
1
              CurVReg =
312
1
                  MIRBuilder
313
1
                      .buildBuildVector({NewLLT}, {CurVReg, Undef.getReg(0)})
314
1
                      .getReg(0);
315
1
            } else {
316
0
              LLVM_DEBUG(dbgs() << "Could not handle ret ty");
317
0
              return false;
318
0
            }
319
119
          } else {
320
119
            // A scalar extend.
321
119
            CurVReg =
322
119
                MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg}).getReg(0);
323
119
          }
324
123
        }
325
248k
      }
326
255k
      if (CurVReg != CurArgInfo.Regs[0]) {
327
7.73k
        CurArgInfo.Regs[0] = CurVReg;
328
7.73k
        // Reset the arg flags after modifying CurVReg.
329
7.73k
        setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
330
7.73k
      }
331
255k
     splitToValueTypes(CurArgInfo, SplitArgs, DL, MRI, CC);
332
255k
    }
333
255k
334
255k
    OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, AssignFn, AssignFn);
335
255k
    Success = handleAssignments(MIRBuilder, SplitArgs, Handler);
336
255k
  }
337
342k
338
342k
  
if (342k
SwiftErrorVReg342k
) {
339
11
    MIB.addUse(AArch64::X21, RegState::Implicit);
340
11
    MIRBuilder.buildCopy(AArch64::X21, SwiftErrorVReg);
341
11
  }
342
342k
343
342k
  MIRBuilder.insertInstr(MIB);
344
342k
  return Success;
345
342k
}
346
347
bool AArch64CallLowering::lowerFormalArguments(
348
    MachineIRBuilder &MIRBuilder, const Function &F,
349
235k
    ArrayRef<ArrayRef<Register>> VRegs) const {
350
235k
  MachineFunction &MF = MIRBuilder.getMF();
351
235k
  MachineBasicBlock &MBB = MIRBuilder.getMBB();
352
235k
  MachineRegisterInfo &MRI = MF.getRegInfo();
353
235k
  auto &DL = F.getParent()->getDataLayout();
354
235k
355
235k
  SmallVector<ArgInfo, 8> SplitArgs;
356
235k
  unsigned i = 0;
357
559k
  for (auto &Arg : F.args()) {
358
559k
    if (DL.getTypeStoreSize(Arg.getType()) == 0)
359
2
      continue;
360
559k
361
559k
    ArgInfo OrigArg{VRegs[i], Arg.getType()};
362
559k
    setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, F);
363
559k
364
559k
    splitToValueTypes(OrigArg, SplitArgs, DL, MRI, F.getCallingConv());
365
559k
    ++i;
366
559k
  }
367
235k
368
235k
  if (!MBB.empty())
369
7
    MIRBuilder.setInstr(*MBB.begin());
370
235k
371
235k
  const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
372
235k
  CCAssignFn *AssignFn =
373
235k
      TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/false);
374
235k
375
235k
  FormalArgHandler Handler(MIRBuilder, MRI, AssignFn);
376
235k
  if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
377
7
    return false;
378
235k
379
235k
  if (F.isVarArg()) {
380
62
    if (!MF.getSubtarget<AArch64Subtarget>().isTargetDarwin()) {
381
0
      // FIXME: we need to reimplement saveVarArgsRegisters from
382
0
      // AArch64ISelLowering.
383
0
      return false;
384
0
    }
385
62
386
62
    // We currently pass all varargs at 8-byte alignment.
387
62
    uint64_t StackOffset = alignTo(Handler.StackUsed, 8);
388
62
389
62
    auto &MFI = MIRBuilder.getMF().getFrameInfo();
390
62
    AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
391
62
    FuncInfo->setVarArgsStackIndex(MFI.CreateFixedObject(4, StackOffset, true));
392
62
  }
393
235k
394
235k
  auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
395
235k
  if (Subtarget.hasCustomCallingConv())
396
10
    Subtarget.getRegisterInfo()->UpdateCustomCalleeSavedRegs(MF);
397
235k
398
235k
  // Move back to the end of the basic block.
399
235k
  MIRBuilder.setMBB(MBB);
400
235k
401
235k
  return true;
402
235k
}
403
404
bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
405
                                    CallingConv::ID CallConv,
406
                                    const MachineOperand &Callee,
407
                                    const ArgInfo &OrigRet,
408
                                    ArrayRef<ArgInfo> OrigArgs,
409
1.25M
                                    Register SwiftErrorVReg) const {
410
1.25M
  MachineFunction &MF = MIRBuilder.getMF();
411
1.25M
  const Function &F = MF.getFunction();
412
1.25M
  MachineRegisterInfo &MRI = MF.getRegInfo();
413
1.25M
  auto &DL = F.getParent()->getDataLayout();
414
1.25M
415
1.25M
  SmallVector<ArgInfo, 8> SplitArgs;
416
2.83M
  for (auto &OrigArg : OrigArgs) {
417
2.83M
    splitToValueTypes(OrigArg, SplitArgs, DL, MRI, CallConv);
418
2.83M
    // AAPCS requires that we zero-extend i1 to 8 bits by the caller.
419
2.83M
    if (OrigArg.Ty->isIntegerTy(1))
420
1.02k
      SplitArgs.back().Flags.setZExt();
421
2.83M
  }
422
1.25M
423
1.25M
  // Find out which ABI gets to decide where things go.
424
1.25M
  const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
425
1.25M
  CCAssignFn *AssignFnFixed =
426
1.25M
      TLI.CCAssignFnForCall(CallConv, /*IsVarArg=*/false);
427
1.25M
  CCAssignFn *AssignFnVarArg =
428
1.25M
      TLI.CCAssignFnForCall(CallConv, /*IsVarArg=*/true);
429
1.25M
430
1.25M
  auto CallSeqStart = MIRBuilder.buildInstr(AArch64::ADJCALLSTACKDOWN);
431
1.25M
432
1.25M
  // Create a temporarily-floating call instruction so we can add the implicit
433
1.25M
  // uses of arg registers.
434
1.25M
  auto MIB = MIRBuilder.buildInstrNoInsert(Callee.isReg() ? 
AArch64::BLR67.3k
435
1.25M
                                                          : 
AArch64::BL1.18M
);
436
1.25M
  MIB.add(Callee);
437
1.25M
438
1.25M
  // Tell the call which registers are clobbered.
439
1.25M
  auto TRI = MF.getSubtarget<AArch64Subtarget>().getRegisterInfo();
440
1.25M
  const uint32_t *Mask = TRI->getCallPreservedMask(MF, F.getCallingConv());
441
1.25M
  if (MF.getSubtarget<AArch64Subtarget>().hasCustomCallingConv())
442
1
    TRI->UpdateCustomCallPreservedMask(MF, &Mask);
443
1.25M
  MIB.addRegMask(Mask);
444
1.25M
445
1.25M
  if (TRI->isAnyArgRegReserved(MF))
446
2
    TRI->emitReservedArgRegCallError(MF);
447
1.25M
448
1.25M
  // Do the actual argument marshalling.
449
1.25M
  SmallVector<unsigned, 8> PhysRegs;
450
1.25M
  OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, AssignFnFixed,
451
1.25M
                             AssignFnVarArg);
452
1.25M
  if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
453
2
    return false;
454
1.25M
455
1.25M
  // Now we can add the actual call instruction to the correct basic block.
456
1.25M
  MIRBuilder.insertInstr(MIB);
457
1.25M
458
1.25M
  // If Callee is a reg, since it is used by a target specific
459
1.25M
  // instruction, it must have a register class matching the
460
1.25M
  // constraint of that instruction.
461
1.25M
  if (Callee.isReg())
462
67.3k
    MIB->getOperand(0).setReg(constrainOperandRegClass(
463
67.3k
        MF, *TRI, MRI, *MF.getSubtarget().getInstrInfo(),
464
67.3k
        *MF.getSubtarget().getRegBankInfo(), *MIB, MIB->getDesc(), Callee, 0));
465
1.25M
466
1.25M
  // Finally we can copy the returned value back into its virtual-register. In
467
1.25M
  // symmetry with the arugments, the physical register must be an
468
1.25M
  // implicit-define of the call instruction.
469
1.25M
  CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
470
1.25M
  if (!OrigRet.Ty->isVoidTy()) {
471
847k
    SplitArgs.clear();
472
847k
473
847k
    splitToValueTypes(OrigRet, SplitArgs, DL, MRI, F.getCallingConv());
474
847k
475
847k
    CallReturnHandler Handler(MIRBuilder, MRI, MIB, RetAssignFn);
476
847k
    if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
477
0
      return false;
478
1.25M
  }
479
1.25M
480
1.25M
  if (SwiftErrorVReg) {
481
12
    MIB.addDef(AArch64::X21, RegState::Implicit);
482
12
    MIRBuilder.buildCopy(SwiftErrorVReg, Register(AArch64::X21));
483
12
  }
484
1.25M
485
1.25M
  CallSeqStart.addImm(Handler.StackSize).addImm(0);
486
1.25M
  MIRBuilder.buildInstr(AArch64::ADJCALLSTACKUP)
487
1.25M
      .addImm(Handler.StackSize)
488
1.25M
      .addImm(0);
489
1.25M
490
1.25M
  return true;
491
1.25M
}