Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Mips/MipsCallLowering.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- MipsCallLowering.cpp -------------------------------------*- C++ -*-===//
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 "MipsCallLowering.h"
16
#include "MipsCCState.h"
17
#include "MipsMachineFunction.h"
18
#include "MipsTargetMachine.h"
19
#include "llvm/CodeGen/Analysis.h"
20
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
21
22
using namespace llvm;
23
24
MipsCallLowering::MipsCallLowering(const MipsTargetLowering &TLI)
25
11.3k
    : CallLowering(&TLI) {}
26
27
bool MipsCallLowering::MipsHandler::assign(Register VReg, const CCValAssign &VA,
28
1.62k
                                           const EVT &VT) {
29
1.62k
  if (VA.isRegLoc()) {
30
1.55k
    assignValueToReg(VReg, VA, VT);
31
1.55k
  } else 
if (67
VA.isMemLoc()67
) {
32
67
    assignValueToAddress(VReg, VA);
33
67
  } else {
34
0
    return false;
35
0
  }
36
1.62k
  return true;
37
1.62k
}
38
39
bool MipsCallLowering::MipsHandler::assignVRegs(ArrayRef<Register> VRegs,
40
                                                ArrayRef<CCValAssign> ArgLocs,
41
                                                unsigned ArgLocsStartIndex,
42
150
                                                const EVT &VT) {
43
468
  for (unsigned i = 0; i < VRegs.size(); 
++i318
)
44
318
    if (!assign(VRegs[i], ArgLocs[ArgLocsStartIndex + i], VT))
45
0
      return false;
46
150
  return true;
47
150
}
48
49
void MipsCallLowering::MipsHandler::setLeastSignificantFirst(
50
150
    SmallVectorImpl<Register> &VRegs) {
51
150
  if (!MIRBuilder.getMF().getDataLayout().isLittleEndian())
52
0
    std::reverse(VRegs.begin(), VRegs.end());
53
150
}
54
55
bool MipsCallLowering::MipsHandler::handle(
56
951
    ArrayRef<CCValAssign> ArgLocs, ArrayRef<CallLowering::ArgInfo> Args) {
57
951
  SmallVector<Register, 4> VRegs;
58
951
  unsigned SplitLength;
59
951
  const Function &F = MIRBuilder.getMF().getFunction();
60
951
  const DataLayout &DL = F.getParent()->getDataLayout();
61
951
  const MipsTargetLowering &TLI = *static_cast<const MipsTargetLowering *>(
62
951
      MIRBuilder.getMF().getSubtarget().getTargetLowering());
63
951
64
2.40k
  for (unsigned ArgsIndex = 0, ArgLocsIndex = 0; ArgsIndex < Args.size();
65
1.45k
       ++ArgsIndex, ArgLocsIndex += SplitLength) {
66
1.45k
    EVT VT = TLI.getValueType(DL, Args[ArgsIndex].Ty);
67
1.45k
    SplitLength = TLI.getNumRegistersForCallingConv(F.getContext(),
68
1.45k
                                                    F.getCallingConv(), VT);
69
1.45k
    assert(Args[ArgsIndex].Regs.size() == 1 && "Can't handle multple regs yet");
70
1.45k
71
1.45k
    if (SplitLength > 1) {
72
150
      VRegs.clear();
73
150
      MVT RegisterVT = TLI.getRegisterTypeForCallingConv(
74
150
          F.getContext(), F.getCallingConv(), VT);
75
468
      for (unsigned i = 0; i < SplitLength; 
++i318
)
76
318
        VRegs.push_back(MRI.createGenericVirtualRegister(LLT{RegisterVT}));
77
150
78
150
      if (!handleSplit(VRegs, ArgLocs, ArgLocsIndex, Args[ArgsIndex].Regs[0],
79
150
                       VT))
80
0
        return false;
81
1.30k
    } else {
82
1.30k
      if (!assign(Args[ArgsIndex].Regs[0], ArgLocs[ArgLocsIndex], VT))
83
0
        return false;
84
1.30k
    }
85
1.45k
  }
86
951
  return true;
87
951
}
88
89
namespace {
90
class IncomingValueHandler : public MipsCallLowering::MipsHandler {
91
public:
92
  IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
93
478
      : MipsHandler(MIRBuilder, MRI) {}
94
95
private:
96
  void assignValueToReg(Register ValVReg, const CCValAssign &VA,
97
                        const EVT &VT) override;
98
99
  Register getStackAddress(const CCValAssign &VA,
100
                           MachineMemOperand *&MMO) override;
101
102
  void assignValueToAddress(Register ValVReg, const CCValAssign &VA) override;
103
104
  bool handleSplit(SmallVectorImpl<Register> &VRegs,
105
                   ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex,
106
                   Register ArgsReg, const EVT &VT) override;
107
108
830
  virtual void markPhysRegUsed(unsigned PhysReg) {
109
830
    MIRBuilder.getMBB().addLiveIn(PhysReg);
110
830
  }
111
112
59
  void buildLoad(Register Val, const CCValAssign &VA) {
113
59
    MachineMemOperand *MMO;
114
59
    Register Addr = getStackAddress(VA, MMO);
115
59
    MIRBuilder.buildLoad(Val, Addr, *MMO);
116
59
  }
117
};
118
119
class CallReturnHandler : public IncomingValueHandler {
120
public:
121
  CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
122
                    MachineInstrBuilder &MIB)
123
98
      : IncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
124
125
private:
126
122
  void markPhysRegUsed(unsigned PhysReg) override {
127
122
    MIB.addDef(PhysReg, RegState::Implicit);
128
122
  }
129
130
  MachineInstrBuilder &MIB;
131
};
132
133
} // end anonymous namespace
134
135
void IncomingValueHandler::assignValueToReg(Register ValVReg,
136
                                            const CCValAssign &VA,
137
944
                                            const EVT &VT) {
138
944
  const MipsSubtarget &STI =
139
944
      static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget());
140
944
  Register PhysReg = VA.getLocReg();
141
944
  if (VT == MVT::f64 && 
PhysReg >= Mips::A0153
&&
PhysReg <= Mips::A3153
) {
142
8
    const MipsSubtarget &STI =
143
8
        static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget());
144
8
145
8
    MIRBuilder
146
8
        .buildInstr(STI.isFP64bit() ? 
Mips::BuildPairF64_644
147
8
                                    : 
Mips::BuildPairF644
)
148
8
        .addDef(ValVReg)
149
8
        .addUse(PhysReg + (STI.isLittle() ? 0 : 
10
))
150
8
        .addUse(PhysReg + (STI.isLittle() ? 1 : 
00
))
151
8
        .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
152
8
                          *STI.getRegBankInfo());
153
8
    markPhysRegUsed(PhysReg);
154
8
    markPhysRegUsed(PhysReg + 1);
155
936
  } else if (VT == MVT::f32 && 
PhysReg >= Mips::A0156
&&
PhysReg <= Mips::A3156
) {
156
12
    MIRBuilder.buildInstr(Mips::MTC1)
157
12
        .addDef(ValVReg)
158
12
        .addUse(PhysReg)
159
12
        .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
160
12
                          *STI.getRegBankInfo());
161
12
    markPhysRegUsed(PhysReg);
162
924
  } else {
163
924
    switch (VA.getLocInfo()) {
164
924
    case CCValAssign::LocInfo::SExt:
165
149
    case CCValAssign::LocInfo::ZExt:
166
149
    case CCValAssign::LocInfo::AExt: {
167
149
      auto Copy = MIRBuilder.buildCopy(LLT{VA.getLocVT()}, PhysReg);
168
149
      MIRBuilder.buildTrunc(ValVReg, Copy);
169
149
      break;
170
149
    }
171
775
    default:
172
775
      MIRBuilder.buildCopy(ValVReg, PhysReg);
173
775
      break;
174
924
    }
175
924
    markPhysRegUsed(PhysReg);
176
924
  }
177
944
}
178
179
Register IncomingValueHandler::getStackAddress(const CCValAssign &VA,
180
59
                                               MachineMemOperand *&MMO) {
181
59
  MachineFunction &MF = MIRBuilder.getMF();
182
59
  unsigned Size = alignTo(VA.getValVT().getSizeInBits(), 8) / 8;
183
59
  unsigned Offset = VA.getLocMemOffset();
184
59
  MachineFrameInfo &MFI = MF.getFrameInfo();
185
59
186
59
  int FI = MFI.CreateFixedObject(Size, Offset, true);
187
59
  MachinePointerInfo MPO =
188
59
      MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
189
59
190
59
  const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering();
191
59
  unsigned Align = MinAlign(TFL->getStackAlignment(), Offset);
192
59
  MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, Size, Align);
193
59
194
59
  Register AddrReg = MRI.createGenericVirtualRegister(LLT::pointer(0, 32));
195
59
  MIRBuilder.buildFrameIndex(AddrReg, FI);
196
59
197
59
  return AddrReg;
198
59
}
199
200
void IncomingValueHandler::assignValueToAddress(Register ValVReg,
201
59
                                                const CCValAssign &VA) {
202
59
  if (VA.getLocInfo() == CCValAssign::SExt ||
203
59
      
VA.getLocInfo() == CCValAssign::ZExt57
||
204
59
      
VA.getLocInfo() == CCValAssign::AExt55
) {
205
8
    Register LoadReg = MRI.createGenericVirtualRegister(LLT::scalar(32));
206
8
    buildLoad(LoadReg, VA);
207
8
    MIRBuilder.buildTrunc(ValVReg, LoadReg);
208
8
  } else
209
51
    buildLoad(ValVReg, VA);
210
59
}
211
212
bool IncomingValueHandler::handleSplit(SmallVectorImpl<Register> &VRegs,
213
                                       ArrayRef<CCValAssign> ArgLocs,
214
                                       unsigned ArgLocsStartIndex,
215
88
                                       Register ArgsReg, const EVT &VT) {
216
88
  if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex, VT))
217
0
    return false;
218
88
  setLeastSignificantFirst(VRegs);
219
88
  MIRBuilder.buildMerge(ArgsReg, VRegs);
220
88
  return true;
221
88
}
222
223
namespace {
224
class OutgoingValueHandler : public MipsCallLowering::MipsHandler {
225
public:
226
  OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
227
                       MachineInstrBuilder &MIB)
228
473
      : MipsHandler(MIRBuilder, MRI), MIB(MIB) {}
229
230
private:
231
  void assignValueToReg(Register ValVReg, const CCValAssign &VA,
232
                        const EVT &VT) override;
233
234
  Register getStackAddress(const CCValAssign &VA,
235
                           MachineMemOperand *&MMO) override;
236
237
  void assignValueToAddress(Register ValVReg, const CCValAssign &VA) override;
238
239
  bool handleSplit(SmallVectorImpl<Register> &VRegs,
240
                   ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex,
241
                   Register ArgsReg, const EVT &VT) override;
242
243
  Register extendRegister(Register ValReg, const CCValAssign &VA);
244
245
  MachineInstrBuilder &MIB;
246
};
247
} // end anonymous namespace
248
249
void OutgoingValueHandler::assignValueToReg(Register ValVReg,
250
                                            const CCValAssign &VA,
251
611
                                            const EVT &VT) {
252
611
  Register PhysReg = VA.getLocReg();
253
611
  const MipsSubtarget &STI =
254
611
      static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget());
255
611
256
611
  if (VT == MVT::f64 && 
PhysReg >= Mips::A077
&&
PhysReg <= Mips::A377
) {
257
4
    MIRBuilder
258
4
        .buildInstr(STI.isFP64bit() ? 
Mips::ExtractElementF64_642
259
4
                                    : 
Mips::ExtractElementF642
)
260
4
        .addDef(PhysReg + (STI.isLittle() ? 1 : 
00
))
261
4
        .addUse(ValVReg)
262
4
        .addImm(1)
263
4
        .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
264
4
                          *STI.getRegBankInfo());
265
4
    MIRBuilder
266
4
        .buildInstr(STI.isFP64bit() ? 
Mips::ExtractElementF64_642
267
4
                                    : 
Mips::ExtractElementF642
)
268
4
        .addDef(PhysReg + (STI.isLittle() ? 0 : 
10
))
269
4
        .addUse(ValVReg)
270
4
        .addImm(0)
271
4
        .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
272
4
                          *STI.getRegBankInfo());
273
607
  } else if (VT == MVT::f32 && 
PhysReg >= Mips::A081
&&
PhysReg <= Mips::A381
) {
274
4
    MIRBuilder.buildInstr(Mips::MFC1)
275
4
        .addDef(PhysReg)
276
4
        .addUse(ValVReg)
277
4
        .constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
278
4
                          *STI.getRegBankInfo());
279
603
  } else {
280
603
    Register ExtReg = extendRegister(ValVReg, VA);
281
603
    MIRBuilder.buildCopy(PhysReg, ExtReg);
282
603
    MIB.addUse(PhysReg, RegState::Implicit);
283
603
  }
284
611
}
285
286
Register OutgoingValueHandler::getStackAddress(const CCValAssign &VA,
287
8
                                               MachineMemOperand *&MMO) {
288
8
  MachineFunction &MF = MIRBuilder.getMF();
289
8
  const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering();
290
8
291
8
  LLT p0 = LLT::pointer(0, 32);
292
8
  LLT s32 = LLT::scalar(32);
293
8
  Register SPReg = MRI.createGenericVirtualRegister(p0);
294
8
  MIRBuilder.buildCopy(SPReg, Register(Mips::SP));
295
8
296
8
  Register OffsetReg = MRI.createGenericVirtualRegister(s32);
297
8
  unsigned Offset = VA.getLocMemOffset();
298
8
  MIRBuilder.buildConstant(OffsetReg, Offset);
299
8
300
8
  Register AddrReg = MRI.createGenericVirtualRegister(p0);
301
8
  MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
302
8
303
8
  MachinePointerInfo MPO =
304
8
      MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
305
8
  unsigned Size = alignTo(VA.getValVT().getSizeInBits(), 8) / 8;
306
8
  unsigned Align = MinAlign(TFL->getStackAlignment(), Offset);
307
8
  MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, Size, Align);
308
8
309
8
  return AddrReg;
310
8
}
311
312
void OutgoingValueHandler::assignValueToAddress(Register ValVReg,
313
8
                                                const CCValAssign &VA) {
314
8
  MachineMemOperand *MMO;
315
8
  Register Addr = getStackAddress(VA, MMO);
316
8
  Register ExtReg = extendRegister(ValVReg, VA);
317
8
  MIRBuilder.buildStore(ExtReg, Addr, *MMO);
318
8
}
319
320
Register OutgoingValueHandler::extendRegister(Register ValReg,
321
611
                                              const CCValAssign &VA) {
322
611
  LLT LocTy{VA.getLocVT()};
323
611
  switch (VA.getLocInfo()) {
324
611
  case CCValAssign::SExt: {
325
31
    Register ExtReg = MRI.createGenericVirtualRegister(LocTy);
326
31
    MIRBuilder.buildSExt(ExtReg, ValReg);
327
31
    return ExtReg;
328
611
  }
329
611
  case CCValAssign::ZExt: {
330
17
    Register ExtReg = MRI.createGenericVirtualRegister(LocTy);
331
17
    MIRBuilder.buildZExt(ExtReg, ValReg);
332
17
    return ExtReg;
333
611
  }
334
611
  case CCValAssign::AExt: {
335
117
    Register ExtReg = MRI.createGenericVirtualRegister(LocTy);
336
117
    MIRBuilder.buildAnyExt(ExtReg, ValReg);
337
117
    return ExtReg;
338
611
  }
339
611
  // TODO : handle upper extends
340
611
  case CCValAssign::Full:
341
446
    return ValReg;
342
611
  default:
343
0
    break;
344
0
  }
345
0
  llvm_unreachable("unable to extend register");
346
0
}
347
348
bool OutgoingValueHandler::handleSplit(SmallVectorImpl<Register> &VRegs,
349
                                       ArrayRef<CCValAssign> ArgLocs,
350
                                       unsigned ArgLocsStartIndex,
351
62
                                       Register ArgsReg, const EVT &VT) {
352
62
  MIRBuilder.buildUnmerge(VRegs, ArgsReg);
353
62
  setLeastSignificantFirst(VRegs);
354
62
  if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex, VT))
355
0
    return false;
356
62
357
62
  return true;
358
62
}
359
360
1.45k
static bool isSupportedType(Type *T) {
361
1.45k
  if (T->isIntegerTy())
362
868
    return true;
363
586
  if (T->isPointerTy())
364
119
    return true;
365
467
  if (T->isFloatingPointTy())
366
467
    return true;
367
0
  return false;
368
0
}
369
370
static CCValAssign::LocInfo determineLocInfo(const MVT RegisterVT, const EVT VT,
371
1.62k
                                             const ISD::ArgFlagsTy &Flags) {
372
1.62k
  // > does not mean loss of information as type RegisterVT can't hold type VT,
373
1.62k
  // it means that type VT is split into multiple registers of type RegisterVT
374
1.62k
  if (VT.getSizeInBits() >= RegisterVT.getSizeInBits())
375
1.30k
    return CCValAssign::LocInfo::Full;
376
322
  if (Flags.isSExt())
377
73
    return CCValAssign::LocInfo::SExt;
378
249
  if (Flags.isZExt())
379
35
    return CCValAssign::LocInfo::ZExt;
380
214
  return CCValAssign::LocInfo::AExt;
381
214
}
382
383
template <typename T>
384
static void setLocInfo(SmallVectorImpl<CCValAssign> &ArgLocs,
385
951
                       const SmallVectorImpl<T> &Arguments) {
386
2.57k
  for (unsigned i = 0; i < ArgLocs.size(); 
++i1.62k
) {
387
1.62k
    const CCValAssign &VA = ArgLocs[i];
388
1.62k
    CCValAssign::LocInfo LocInfo = determineLocInfo(
389
1.62k
        Arguments[i].VT, Arguments[i].ArgVT, Arguments[i].Flags);
390
1.62k
    if (VA.isMemLoc())
391
67
      ArgLocs[i] =
392
67
          CCValAssign::getMem(VA.getValNo(), VA.getValVT(),
393
67
                              VA.getLocMemOffset(), VA.getLocVT(), LocInfo);
394
1.55k
    else
395
1.55k
      ArgLocs[i] = CCValAssign::getReg(VA.getValNo(), VA.getValVT(),
396
1.55k
                                       VA.getLocReg(), VA.getLocVT(), LocInfo);
397
1.62k
  }
398
951
}
MipsCallLowering.cpp:void setLocInfo<llvm::ISD::OutputArg>(llvm::SmallVectorImpl<llvm::CCValAssign>&, llvm::SmallVectorImpl<llvm::ISD::OutputArg> const&)
Line
Count
Source
385
473
                       const SmallVectorImpl<T> &Arguments) {
386
1.09k
  for (unsigned i = 0; i < ArgLocs.size(); 
++i619
) {
387
619
    const CCValAssign &VA = ArgLocs[i];
388
619
    CCValAssign::LocInfo LocInfo = determineLocInfo(
389
619
        Arguments[i].VT, Arguments[i].ArgVT, Arguments[i].Flags);
390
619
    if (VA.isMemLoc())
391
8
      ArgLocs[i] =
392
8
          CCValAssign::getMem(VA.getValNo(), VA.getValVT(),
393
8
                              VA.getLocMemOffset(), VA.getLocVT(), LocInfo);
394
611
    else
395
611
      ArgLocs[i] = CCValAssign::getReg(VA.getValNo(), VA.getValVT(),
396
611
                                       VA.getLocReg(), VA.getLocVT(), LocInfo);
397
619
  }
398
473
}
MipsCallLowering.cpp:void setLocInfo<llvm::ISD::InputArg>(llvm::SmallVectorImpl<llvm::CCValAssign>&, llvm::SmallVectorImpl<llvm::ISD::InputArg> const&)
Line
Count
Source
385
478
                       const SmallVectorImpl<T> &Arguments) {
386
1.48k
  for (unsigned i = 0; i < ArgLocs.size(); 
++i1.00k
) {
387
1.00k
    const CCValAssign &VA = ArgLocs[i];
388
1.00k
    CCValAssign::LocInfo LocInfo = determineLocInfo(
389
1.00k
        Arguments[i].VT, Arguments[i].ArgVT, Arguments[i].Flags);
390
1.00k
    if (VA.isMemLoc())
391
59
      ArgLocs[i] =
392
59
          CCValAssign::getMem(VA.getValNo(), VA.getValVT(),
393
59
                              VA.getLocMemOffset(), VA.getLocVT(), LocInfo);
394
944
    else
395
944
      ArgLocs[i] = CCValAssign::getReg(VA.getValNo(), VA.getValVT(),
396
944
                                       VA.getLocReg(), VA.getLocVT(), LocInfo);
397
1.00k
  }
398
478
}
399
400
bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
401
                                   const Value *Val,
402
419
                                   ArrayRef<Register> VRegs) const {
403
419
404
419
  MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(Mips::RetRA);
405
419
406
419
  if (Val != nullptr && 
!isSupportedType(Val->getType())373
)
407
0
    return false;
408
419
409
419
  if (!VRegs.empty()) {
410
373
    MachineFunction &MF = MIRBuilder.getMF();
411
373
    const Function &F = MF.getFunction();
412
373
    const DataLayout &DL = MF.getDataLayout();
413
373
    const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
414
373
    LLVMContext &Ctx = Val->getType()->getContext();
415
373
416
373
    SmallVector<EVT, 4> SplitEVTs;
417
373
    ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs);
418
373
    assert(VRegs.size() == SplitEVTs.size() &&
419
373
           "For each split Type there should be exactly one VReg.");
420
373
421
373
    SmallVector<ArgInfo, 8> RetInfos;
422
373
    SmallVector<unsigned, 8> OrigArgIndices;
423
373
424
746
    for (unsigned i = 0; i < SplitEVTs.size(); 
++i373
) {
425
373
      ArgInfo CurArgInfo = ArgInfo{VRegs[i], SplitEVTs[i].getTypeForEVT(Ctx)};
426
373
      setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
427
373
      splitToValueTypes(CurArgInfo, 0, RetInfos, OrigArgIndices);
428
373
    }
429
373
430
373
    SmallVector<ISD::OutputArg, 8> Outs;
431
373
    subTargetRegTypeForCallingConv(F, RetInfos, OrigArgIndices, Outs);
432
373
433
373
    SmallVector<CCValAssign, 16> ArgLocs;
434
373
    MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
435
373
                       F.getContext());
436
373
    CCInfo.AnalyzeReturn(Outs, TLI.CCAssignFnForReturn());
437
373
    setLocInfo(ArgLocs, Outs);
438
373
439
373
    OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
440
373
    if (!RetHandler.handle(ArgLocs, RetInfos)) {
441
0
      return false;
442
0
    }
443
419
  }
444
419
  MIRBuilder.insertInstr(Ret);
445
419
  return true;
446
419
}
447
448
bool MipsCallLowering::lowerFormalArguments(
449
    MachineIRBuilder &MIRBuilder, const Function &F,
450
402
    ArrayRef<ArrayRef<Register>> VRegs) const {
451
402
452
402
  // Quick exit if there aren't any args.
453
402
  if (F.arg_empty())
454
22
    return true;
455
380
456
380
  if (F.isVarArg()) {
457
0
    return false;
458
0
  }
459
380
460
805
  
for (auto &Arg : F.args())380
{
461
805
    if (!isSupportedType(Arg.getType()))
462
0
      return false;
463
805
  }
464
380
465
380
  MachineFunction &MF = MIRBuilder.getMF();
466
380
  const DataLayout &DL = MF.getDataLayout();
467
380
  const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
468
380
469
380
  SmallVector<ArgInfo, 8> ArgInfos;
470
380
  SmallVector<unsigned, 8> OrigArgIndices;
471
380
  unsigned i = 0;
472
805
  for (auto &Arg : F.args()) {
473
805
    ArgInfo AInfo(VRegs[i], Arg.getType());
474
805
    setArgFlags(AInfo, i + AttributeList::FirstArgIndex, DL, F);
475
805
    splitToValueTypes(AInfo, i, ArgInfos, OrigArgIndices);
476
805
    ++i;
477
805
  }
478
380
479
380
  SmallVector<ISD::InputArg, 8> Ins;
480
380
  subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Ins);
481
380
482
380
  SmallVector<CCValAssign, 16> ArgLocs;
483
380
  MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
484
380
                     F.getContext());
485
380
486
380
  const MipsTargetMachine &TM =
487
380
      static_cast<const MipsTargetMachine &>(MF.getTarget());
488
380
  const MipsABIInfo &ABI = TM.getABI();
489
380
  CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(F.getCallingConv()),
490
380
                       1);
491
380
  CCInfo.AnalyzeFormalArguments(Ins, TLI.CCAssignFnForCall());
492
380
  setLocInfo(ArgLocs, Ins);
493
380
494
380
  IncomingValueHandler Handler(MIRBuilder, MF.getRegInfo());
495
380
  if (!Handler.handle(ArgLocs, ArgInfos))
496
0
    return false;
497
380
498
380
  return true;
499
380
}
500
501
bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
502
                                 CallingConv::ID CallConv,
503
                                 const MachineOperand &Callee,
504
                                 const ArgInfo &OrigRet,
505
100
                                 ArrayRef<ArgInfo> OrigArgs) const {
506
100
507
100
  if (CallConv != CallingConv::C)
508
0
    return false;
509
100
510
178
  
for (auto &Arg : OrigArgs)100
{
511
178
    if (!isSupportedType(Arg.Ty))
512
0
      return false;
513
178
    if (Arg.Flags.isByVal() || Arg.Flags.isSRet())
514
0
      return false;
515
178
  }
516
100
517
100
  if (OrigRet.Regs[0] && 
!isSupportedType(OrigRet.Ty)98
)
518
0
    return false;
519
100
520
100
  MachineFunction &MF = MIRBuilder.getMF();
521
100
  const Function &F = MF.getFunction();
522
100
  const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
523
100
  const MipsTargetMachine &TM =
524
100
      static_cast<const MipsTargetMachine &>(MF.getTarget());
525
100
  const MipsABIInfo &ABI = TM.getABI();
526
100
527
100
  MachineInstrBuilder CallSeqStart =
528
100
      MIRBuilder.buildInstr(Mips::ADJCALLSTACKDOWN);
529
100
530
100
  const bool IsCalleeGlobalPIC =
531
100
      Callee.isGlobal() && 
TM.isPositionIndependent()38
;
532
100
533
100
  MachineInstrBuilder MIB = MIRBuilder.buildInstrNoInsert(
534
100
      Callee.isReg() || 
IsCalleeGlobalPIC96
?
Mips::JALRPseudo12
:
Mips::JAL88
);
535
100
  MIB.addDef(Mips::SP, RegState::Implicit);
536
100
  if (IsCalleeGlobalPIC) {
537
8
    Register CalleeReg =
538
8
        MF.getRegInfo().createGenericVirtualRegister(LLT::pointer(0, 32));
539
8
    MachineInstr *CalleeGlobalValue =
540
8
        MIRBuilder.buildGlobalValue(CalleeReg, Callee.getGlobal());
541
8
    if (!Callee.getGlobal()->hasLocalLinkage())
542
4
      CalleeGlobalValue->getOperand(1).setTargetFlags(MipsII::MO_GOT_CALL);
543
8
    MIB.addUse(CalleeReg);
544
8
  } else
545
92
    MIB.add(Callee);
546
100
  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
547
100
  MIB.addRegMask(TRI->getCallPreservedMask(MF, F.getCallingConv()));
548
100
549
100
  TargetLowering::ArgListTy FuncOrigArgs;
550
100
  FuncOrigArgs.reserve(OrigArgs.size());
551
100
552
100
  SmallVector<ArgInfo, 8> ArgInfos;
553
100
  SmallVector<unsigned, 8> OrigArgIndices;
554
100
  unsigned i = 0;
555
178
  for (auto &Arg : OrigArgs) {
556
178
557
178
    TargetLowering::ArgListEntry Entry;
558
178
    Entry.Ty = Arg.Ty;
559
178
    FuncOrigArgs.push_back(Entry);
560
178
561
178
    splitToValueTypes(Arg, i, ArgInfos, OrigArgIndices);
562
178
    ++i;
563
178
  }
564
100
565
100
  SmallVector<ISD::OutputArg, 8> Outs;
566
100
  subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Outs);
567
100
568
100
  SmallVector<CCValAssign, 8> ArgLocs;
569
100
  MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
570
100
                     F.getContext());
571
100
572
100
  CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(CallConv), 1);
573
100
  const char *Call = Callee.isSymbol() ? 
Callee.getSymbolName()58
:
nullptr42
;
574
100
  CCInfo.AnalyzeCallOperands(Outs, TLI.CCAssignFnForCall(), FuncOrigArgs, Call);
575
100
  setLocInfo(ArgLocs, Outs);
576
100
577
100
  OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), MIB);
578
100
  if (!RetHandler.handle(ArgLocs, ArgInfos)) {
579
0
    return false;
580
0
  }
581
100
582
100
  unsigned NextStackOffset = CCInfo.getNextStackOffset();
583
100
  const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering();
584
100
  unsigned StackAlignment = TFL->getStackAlignment();
585
100
  NextStackOffset = alignTo(NextStackOffset, StackAlignment);
586
100
  CallSeqStart.addImm(NextStackOffset).addImm(0);
587
100
588
100
  if (IsCalleeGlobalPIC) {
589
8
    MIRBuilder.buildCopy(
590
8
      Register(Mips::GP),
591
8
      MF.getInfo<MipsFunctionInfo>()->getGlobalBaseRegForGlobalISel());
592
8
    MIB.addDef(Mips::GP, RegState::Implicit);
593
8
  }
594
100
  MIRBuilder.insertInstr(MIB);
595
100
  if (MIB->getOpcode() == Mips::JALRPseudo) {
596
12
    const MipsSubtarget &STI =
597
12
        static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget());
598
12
    MIB.constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
599
12
                         *STI.getRegBankInfo());
600
12
  }
601
100
602
100
  if (OrigRet.Regs[0]) {
603
98
    ArgInfos.clear();
604
98
    SmallVector<unsigned, 8> OrigRetIndices;
605
98
606
98
    splitToValueTypes(OrigRet, 0, ArgInfos, OrigRetIndices);
607
98
608
98
    SmallVector<ISD::InputArg, 8> Ins;
609
98
    subTargetRegTypeForCallingConv(F, ArgInfos, OrigRetIndices, Ins);
610
98
611
98
    SmallVector<CCValAssign, 8> ArgLocs;
612
98
    MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
613
98
                       F.getContext());
614
98
615
98
    CCInfo.AnalyzeCallResult(Ins, TLI.CCAssignFnForReturn(), OrigRet.Ty, Call);
616
98
    setLocInfo(ArgLocs, Ins);
617
98
618
98
    CallReturnHandler Handler(MIRBuilder, MF.getRegInfo(), MIB);
619
98
    if (!Handler.handle(ArgLocs, ArgInfos))
620
0
      return false;
621
100
  }
622
100
623
100
  MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP).addImm(NextStackOffset).addImm(0);
624
100
625
100
  return true;
626
100
}
627
628
template <typename T>
629
void MipsCallLowering::subTargetRegTypeForCallingConv(
630
    const Function &F, ArrayRef<ArgInfo> Args,
631
951
    ArrayRef<unsigned> OrigArgIndices, SmallVectorImpl<T> &ISDArgs) const {
632
951
  const DataLayout &DL = F.getParent()->getDataLayout();
633
951
  const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
634
951
635
951
  unsigned ArgNo = 0;
636
1.45k
  for (auto &Arg : Args) {
637
1.45k
638
1.45k
    EVT VT = TLI.getValueType(DL, Arg.Ty);
639
1.45k
    MVT RegisterVT = TLI.getRegisterTypeForCallingConv(F.getContext(),
640
1.45k
                                                       F.getCallingConv(), VT);
641
1.45k
    unsigned NumRegs = TLI.getNumRegistersForCallingConv(
642
1.45k
        F.getContext(), F.getCallingConv(), VT);
643
1.45k
644
3.07k
    for (unsigned i = 0; i < NumRegs; 
++i1.62k
) {
645
1.62k
      ISD::ArgFlagsTy Flags = Arg.Flags;
646
1.62k
647
1.62k
      if (i == 0)
648
1.45k
        Flags.setOrigAlign(TLI.getABIAlignmentForCallingConv(Arg.Ty, DL));
649
168
      else
650
168
        Flags.setOrigAlign(1);
651
1.62k
652
1.62k
      ISDArgs.emplace_back(Flags, RegisterVT, VT, true, OrigArgIndices[ArgNo],
653
1.62k
                           0);
654
1.62k
    }
655
1.45k
    ++ArgNo;
656
1.45k
  }
657
951
}
void llvm::MipsCallLowering::subTargetRegTypeForCallingConv<llvm::ISD::OutputArg>(llvm::Function const&, llvm::ArrayRef<llvm::CallLowering::ArgInfo>, llvm::ArrayRef<unsigned int>, llvm::SmallVectorImpl<llvm::ISD::OutputArg>&) const
Line
Count
Source
631
473
    ArrayRef<unsigned> OrigArgIndices, SmallVectorImpl<T> &ISDArgs) const {
632
473
  const DataLayout &DL = F.getParent()->getDataLayout();
633
473
  const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
634
473
635
473
  unsigned ArgNo = 0;
636
551
  for (auto &Arg : Args) {
637
551
638
551
    EVT VT = TLI.getValueType(DL, Arg.Ty);
639
551
    MVT RegisterVT = TLI.getRegisterTypeForCallingConv(F.getContext(),
640
551
                                                       F.getCallingConv(), VT);
641
551
    unsigned NumRegs = TLI.getNumRegistersForCallingConv(
642
551
        F.getContext(), F.getCallingConv(), VT);
643
551
644
1.17k
    for (unsigned i = 0; i < NumRegs; 
++i619
) {
645
619
      ISD::ArgFlagsTy Flags = Arg.Flags;
646
619
647
619
      if (i == 0)
648
551
        Flags.setOrigAlign(TLI.getABIAlignmentForCallingConv(Arg.Ty, DL));
649
68
      else
650
68
        Flags.setOrigAlign(1);
651
619
652
619
      ISDArgs.emplace_back(Flags, RegisterVT, VT, true, OrigArgIndices[ArgNo],
653
619
                           0);
654
619
    }
655
551
    ++ArgNo;
656
551
  }
657
473
}
void llvm::MipsCallLowering::subTargetRegTypeForCallingConv<llvm::ISD::InputArg>(llvm::Function const&, llvm::ArrayRef<llvm::CallLowering::ArgInfo>, llvm::ArrayRef<unsigned int>, llvm::SmallVectorImpl<llvm::ISD::InputArg>&) const
Line
Count
Source
631
478
    ArrayRef<unsigned> OrigArgIndices, SmallVectorImpl<T> &ISDArgs) const {
632
478
  const DataLayout &DL = F.getParent()->getDataLayout();
633
478
  const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();
634
478
635
478
  unsigned ArgNo = 0;
636
903
  for (auto &Arg : Args) {
637
903
638
903
    EVT VT = TLI.getValueType(DL, Arg.Ty);
639
903
    MVT RegisterVT = TLI.getRegisterTypeForCallingConv(F.getContext(),
640
903
                                                       F.getCallingConv(), VT);
641
903
    unsigned NumRegs = TLI.getNumRegistersForCallingConv(
642
903
        F.getContext(), F.getCallingConv(), VT);
643
903
644
1.90k
    for (unsigned i = 0; i < NumRegs; 
++i1.00k
) {
645
1.00k
      ISD::ArgFlagsTy Flags = Arg.Flags;
646
1.00k
647
1.00k
      if (i == 0)
648
903
        Flags.setOrigAlign(TLI.getABIAlignmentForCallingConv(Arg.Ty, DL));
649
100
      else
650
100
        Flags.setOrigAlign(1);
651
1.00k
652
1.00k
      ISDArgs.emplace_back(Flags, RegisterVT, VT, true, OrigArgIndices[ArgNo],
653
1.00k
                           0);
654
1.00k
    }
655
903
    ++ArgNo;
656
903
  }
657
478
}
658
659
void MipsCallLowering::splitToValueTypes(
660
    const ArgInfo &OrigArg, unsigned OriginalIndex,
661
    SmallVectorImpl<ArgInfo> &SplitArgs,
662
1.45k
    SmallVectorImpl<unsigned> &SplitArgsOrigIndices) const {
663
1.45k
664
1.45k
  // TODO : perform structure and array split. For now we only deal with
665
1.45k
  // types that pass isSupportedType check.
666
1.45k
  SplitArgs.push_back(OrigArg);
667
1.45k
  SplitArgsOrigIndices.push_back(OriginalIndex);
668
1.45k
}