Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- AArch64RegisterBankInfo.cpp ----------------------------------------===//
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
/// \file
9
/// This file implements the targeting of the RegisterBankInfo class for
10
/// AArch64.
11
/// \todo This should be generated by TableGen.
12
//===----------------------------------------------------------------------===//
13
14
#include "AArch64RegisterBankInfo.h"
15
#include "AArch64InstrInfo.h"
16
#include "llvm/ADT/SmallVector.h"
17
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
18
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
19
#include "llvm/CodeGen/LowLevelType.h"
20
#include "llvm/CodeGen/MachineFunction.h"
21
#include "llvm/CodeGen/MachineInstr.h"
22
#include "llvm/CodeGen/MachineOperand.h"
23
#include "llvm/CodeGen/MachineRegisterInfo.h"
24
#include "llvm/CodeGen/TargetOpcodes.h"
25
#include "llvm/CodeGen/TargetRegisterInfo.h"
26
#include "llvm/CodeGen/TargetSubtargetInfo.h"
27
#include "llvm/Support/ErrorHandling.h"
28
#include <algorithm>
29
#include <cassert>
30
31
#define GET_TARGET_REGBANK_IMPL
32
#include "AArch64GenRegisterBank.inc"
33
34
// This file will be TableGen'ed at some point.
35
#include "AArch64GenRegisterBankInfo.def"
36
37
using namespace llvm;
38
39
AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
40
9.10k
    : AArch64GenRegisterBankInfo() {
41
9.10k
  static bool AlreadyInit = false;
42
9.10k
  // We have only one set of register banks, whatever the subtarget
43
9.10k
  // is. Therefore, the initialization of the RegBanks table should be
44
9.10k
  // done only once. Indeed the table of all register banks
45
9.10k
  // (AArch64::RegBanks) is unique in the compiler. At some point, it
46
9.10k
  // will get tablegen'ed and the whole constructor becomes empty.
47
9.10k
  if (AlreadyInit)
48
23
    return;
49
9.08k
  AlreadyInit = true;
50
9.08k
51
9.08k
  const RegisterBank &RBGPR = getRegBank(AArch64::GPRRegBankID);
52
9.08k
  (void)RBGPR;
53
9.08k
  assert(&AArch64::GPRRegBank == &RBGPR &&
54
9.08k
         "The order in RegBanks is messed up");
55
9.08k
56
9.08k
  const RegisterBank &RBFPR = getRegBank(AArch64::FPRRegBankID);
57
9.08k
  (void)RBFPR;
58
9.08k
  assert(&AArch64::FPRRegBank == &RBFPR &&
59
9.08k
         "The order in RegBanks is messed up");
60
9.08k
61
9.08k
  const RegisterBank &RBCCR = getRegBank(AArch64::CCRegBankID);
62
9.08k
  (void)RBCCR;
63
9.08k
  assert(&AArch64::CCRegBank == &RBCCR && "The order in RegBanks is messed up");
64
9.08k
65
9.08k
  // The GPR register bank is fully defined by all the registers in
66
9.08k
  // GR64all + its subclasses.
67
9.08k
  assert(RBGPR.covers(*TRI.getRegClass(AArch64::GPR32RegClassID)) &&
68
9.08k
         "Subclass not added?");
69
9.08k
  assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
70
9.08k
71
9.08k
  // The FPR register bank is fully defined by all the registers in
72
9.08k
  // GR64all + its subclasses.
73
9.08k
  assert(RBFPR.covers(*TRI.getRegClass(AArch64::QQRegClassID)) &&
74
9.08k
         "Subclass not added?");
75
9.08k
  assert(RBFPR.covers(*TRI.getRegClass(AArch64::FPR64RegClassID)) &&
76
9.08k
         "Subclass not added?");
77
9.08k
  assert(RBFPR.getSize() == 512 &&
78
9.08k
         "FPRs should hold up to 512-bit via QQQQ sequence");
79
9.08k
80
9.08k
  assert(RBCCR.covers(*TRI.getRegClass(AArch64::CCRRegClassID)) &&
81
9.08k
         "Class not added?");
82
9.08k
  assert(RBCCR.getSize() == 32 && "CCR should hold up to 32-bit");
83
9.08k
84
9.08k
  // Check that the TableGen'ed like file is in sync we our expectations.
85
9.08k
  // First, the Idx.
86
9.08k
  assert(checkPartialMappingIdx(PMI_FirstGPR, PMI_LastGPR,
87
9.08k
                                {PMI_GPR32, PMI_GPR64}) &&
88
9.08k
         "PartialMappingIdx's are incorrectly ordered");
89
9.08k
  assert(checkPartialMappingIdx(PMI_FirstFPR, PMI_LastFPR,
90
9.08k
                                {PMI_FPR16, PMI_FPR32, PMI_FPR64, PMI_FPR128,
91
9.08k
                                 PMI_FPR256, PMI_FPR512}) &&
92
9.08k
         "PartialMappingIdx's are incorrectly ordered");
93
9.08k
// Now, the content.
94
9.08k
// Check partial mapping.
95
9.08k
#define CHECK_PARTIALMAP(Idx, ValStartIdx, ValLength, RB)                      \
96
72.6k
  do {                                                                         \
97
72.6k
    assert(                                                                    \
98
72.6k
        checkPartialMap(PartialMappingIdx::Idx, ValStartIdx, ValLength, RB) && \
99
72.6k
        #Idx " is incorrectly initialized");                                   \
100
72.6k
  } while (false)
101
9.08k
102
9.08k
  CHECK_PARTIALMAP(PMI_GPR32, 0, 32, RBGPR);
103
9.08k
  CHECK_PARTIALMAP(PMI_GPR64, 0, 64, RBGPR);
104
9.08k
  CHECK_PARTIALMAP(PMI_FPR16, 0, 16, RBFPR);
105
9.08k
  CHECK_PARTIALMAP(PMI_FPR32, 0, 32, RBFPR);
106
9.08k
  CHECK_PARTIALMAP(PMI_FPR64, 0, 64, RBFPR);
107
9.08k
  CHECK_PARTIALMAP(PMI_FPR128, 0, 128, RBFPR);
108
9.08k
  CHECK_PARTIALMAP(PMI_FPR256, 0, 256, RBFPR);
109
9.08k
  CHECK_PARTIALMAP(PMI_FPR512, 0, 512, RBFPR);
110
9.08k
111
9.08k
// Check value mapping.
112
9.08k
#define CHECK_VALUEMAP_IMPL(RBName, Size, Offset)                              \
113
263k
  do {                                                                         \
114
263k
    assert(checkValueMapImpl(PartialMappingIdx::PMI_##RBName##Size,            \
115
263k
                             PartialMappingIdx::PMI_First##RBName, Size,       \
116
263k
                             Offset) &&                                        \
117
263k
           #RBName #Size " " #Offset " is incorrectly initialized");           \
118
263k
  } while (false)
119
9.08k
120
72.6k
#define CHECK_VALUEMAP(RBName, Size) CHECK_VALUEMAP_IMPL(RBName, Size, 0)
121
9.08k
122
9.08k
  CHECK_VALUEMAP(GPR, 32);
123
9.08k
  CHECK_VALUEMAP(GPR, 64);
124
9.08k
  CHECK_VALUEMAP(FPR, 16);
125
9.08k
  CHECK_VALUEMAP(FPR, 32);
126
9.08k
  CHECK_VALUEMAP(FPR, 64);
127
9.08k
  CHECK_VALUEMAP(FPR, 128);
128
9.08k
  CHECK_VALUEMAP(FPR, 256);
129
9.08k
  CHECK_VALUEMAP(FPR, 512);
130
9.08k
131
9.08k
// Check the value mapping for 3-operands instructions where all the operands
132
9.08k
// map to the same value mapping.
133
9.08k
#define CHECK_VALUEMAP_3OPS(RBName, Size)                                      \
134
63.5k
  do {                                                                         \
135
63.5k
    CHECK_VALUEMAP_IMPL(RBName, Size, 0);                                      \
136
63.5k
    CHECK_VALUEMAP_IMPL(RBName, Size, 1);                                      \
137
63.5k
    CHECK_VALUEMAP_IMPL(RBName, Size, 2);                                      \
138
63.5k
  } while (false)
139
9.08k
140
9.08k
  CHECK_VALUEMAP_3OPS(GPR, 32);
141
9.08k
  CHECK_VALUEMAP_3OPS(GPR, 64);
142
9.08k
  CHECK_VALUEMAP_3OPS(FPR, 32);
143
9.08k
  CHECK_VALUEMAP_3OPS(FPR, 64);
144
9.08k
  CHECK_VALUEMAP_3OPS(FPR, 128);
145
9.08k
  CHECK_VALUEMAP_3OPS(FPR, 256);
146
9.08k
  CHECK_VALUEMAP_3OPS(FPR, 512);
147
9.08k
148
9.08k
#define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size)                 \
149
72.6k
  do {                                                                         \
150
72.6k
    unsigned PartialMapDstIdx = PMI_##RBNameDst##Size - PMI_Min;               \
151
72.6k
    unsigned PartialMapSrcIdx = PMI_##RBNameSrc##Size - PMI_Min;               \
152
72.6k
    (void)PartialMapDstIdx;                                                    \
153
72.6k
    (void)PartialMapSrcIdx;                                                    \
154
72.6k
    const ValueMapping *Map = getCopyMapping(                                  \
155
72.6k
        AArch64::RBNameDst##RegBankID, AArch64::RBNameSrc##RegBankID, Size);  \
156
72.6k
    (void)Map;                                                                 \
157
72.6k
    assert(Map[0].BreakDown ==                                                 \
158
72.6k
               &AArch64GenRegisterBankInfo::PartMappings[PartialMapDstIdx] &&  \
159
72.6k
           Map[0].NumBreakDowns == 1 && #RBNameDst #Size                       \
160
72.6k
           " Dst is incorrectly initialized");                                 \
161
72.6k
    assert(Map[1].BreakDown ==                                                 \
162
72.6k
               &AArch64GenRegisterBankInfo::PartMappings[PartialMapSrcIdx] &&  \
163
72.6k
           Map[1].NumBreakDowns == 1 && #RBNameSrc #Size                       \
164
72.6k
           " Src is incorrectly initialized");                                 \
165
72.6k
                                                                               \
166
72.6k
  } while (false)
167
9.08k
168
9.08k
  CHECK_VALUEMAP_CROSSREGCPY(GPR, GPR, 32);
169
9.08k
  CHECK_VALUEMAP_CROSSREGCPY(GPR, FPR, 32);
170
9.08k
  CHECK_VALUEMAP_CROSSREGCPY(GPR, GPR, 64);
171
9.08k
  CHECK_VALUEMAP_CROSSREGCPY(GPR, FPR, 64);
172
9.08k
  CHECK_VALUEMAP_CROSSREGCPY(FPR, FPR, 32);
173
9.08k
  CHECK_VALUEMAP_CROSSREGCPY(FPR, GPR, 32);
174
9.08k
  CHECK_VALUEMAP_CROSSREGCPY(FPR, FPR, 64);
175
9.08k
  CHECK_VALUEMAP_CROSSREGCPY(FPR, GPR, 64);
176
9.08k
177
9.08k
#define CHECK_VALUEMAP_FPEXT(DstSize, SrcSize)                                 \
178
36.3k
  do {                                                                         \
179
36.3k
    unsigned PartialMapDstIdx = PMI_FPR##DstSize - PMI_Min;                    \
180
36.3k
    unsigned PartialMapSrcIdx = PMI_FPR##SrcSize - PMI_Min;                    \
181
36.3k
    (void)PartialMapDstIdx;                                                    \
182
36.3k
    (void)PartialMapSrcIdx;                                                    \
183
36.3k
    const ValueMapping *Map = getFPExtMapping(DstSize, SrcSize);               \
184
36.3k
    (void)Map;                                                                 \
185
36.3k
    assert(Map[0].BreakDown ==                                                 \
186
36.3k
               &AArch64GenRegisterBankInfo::PartMappings[PartialMapDstIdx] &&  \
187
36.3k
           Map[0].NumBreakDowns == 1 && "FPR" #DstSize                         \
188
36.3k
                                        " Dst is incorrectly initialized");    \
189
36.3k
    assert(Map[1].BreakDown ==                                                 \
190
36.3k
               &AArch64GenRegisterBankInfo::PartMappings[PartialMapSrcIdx] &&  \
191
36.3k
           Map[1].NumBreakDowns == 1 && "FPR" #SrcSize                         \
192
36.3k
                                        " Src is incorrectly initialized");    \
193
36.3k
                                                                               \
194
36.3k
  } while (false)
195
9.08k
196
9.08k
  CHECK_VALUEMAP_FPEXT(32, 16);
197
9.08k
  CHECK_VALUEMAP_FPEXT(64, 16);
198
9.08k
  CHECK_VALUEMAP_FPEXT(64, 32);
199
9.08k
  CHECK_VALUEMAP_FPEXT(128, 64);
200
9.08k
201
9.08k
  assert(verify(TRI) && "Invalid register bank information");
202
9.08k
}
203
204
unsigned AArch64RegisterBankInfo::copyCost(const RegisterBank &A,
205
                                           const RegisterBank &B,
206
5.03M
                                           unsigned Size) const {
207
5.03M
  // What do we do with different size?
208
5.03M
  // copy are same size.
209
5.03M
  // Will introduce other hooks for different size:
210
5.03M
  // * extract cost.
211
5.03M
  // * build_sequence cost.
212
5.03M
213
5.03M
  // Copy from (resp. to) GPR to (resp. from) FPR involves FMOV.
214
5.03M
  // FIXME: This should be deduced from the scheduling model.
215
5.03M
  if (&A == &AArch64::GPRRegBank && 
&B == &AArch64::FPRRegBank4.96M
)
216
1.30k
    // FMOVXDr or FMOVWSr.
217
1.30k
    return 5;
218
5.03M
  if (&A == &AArch64::FPRRegBank && 
&B == &AArch64::GPRRegBank70.3k
)
219
542
    // FMOVDXr or FMOVSWr.
220
542
    return 4;
221
5.03M
222
5.03M
  return RegisterBankInfo::copyCost(A, B, Size);
223
5.03M
}
224
225
const RegisterBank &AArch64RegisterBankInfo::getRegBankFromRegClass(
226
29.9M
    const TargetRegisterClass &RC) const {
227
29.9M
  switch (RC.getID()) {
228
29.9M
  case AArch64::FPR8RegClassID:
229
1.77M
  case AArch64::FPR16RegClassID:
230
1.77M
  case AArch64::FPR32RegClassID:
231
1.77M
  case AArch64::FPR64RegClassID:
232
1.77M
  case AArch64::FPR128RegClassID:
233
1.77M
  case AArch64::FPR128_loRegClassID:
234
1.77M
  case AArch64::DDRegClassID:
235
1.77M
  case AArch64::DDDRegClassID:
236
1.77M
  case AArch64::DDDDRegClassID:
237
1.77M
  case AArch64::QQRegClassID:
238
1.77M
  case AArch64::QQQRegClassID:
239
1.77M
  case AArch64::QQQQRegClassID:
240
1.77M
    return getRegBank(AArch64::FPRRegBankID);
241
28.1M
  case AArch64::GPR32commonRegClassID:
242
28.1M
  case AArch64::GPR32RegClassID:
243
28.1M
  case AArch64::GPR32spRegClassID:
244
28.1M
  case AArch64::GPR32sponlyRegClassID:
245
28.1M
  case AArch64::GPR32argRegClassID:
246
28.1M
  case AArch64::GPR32allRegClassID:
247
28.1M
  case AArch64::GPR64commonRegClassID:
248
28.1M
  case AArch64::GPR64RegClassID:
249
28.1M
  case AArch64::GPR64spRegClassID:
250
28.1M
  case AArch64::GPR64sponlyRegClassID:
251
28.1M
  case AArch64::GPR64argRegClassID:
252
28.1M
  case AArch64::GPR64allRegClassID:
253
28.1M
  case AArch64::GPR64noipRegClassID:
254
28.1M
  case AArch64::GPR64common_and_GPR64noipRegClassID:
255
28.1M
  case AArch64::GPR64noip_and_tcGPR64RegClassID:
256
28.1M
  case AArch64::tcGPR64RegClassID:
257
28.1M
  case AArch64::WSeqPairsClassRegClassID:
258
28.1M
  case AArch64::XSeqPairsClassRegClassID:
259
28.1M
    return getRegBank(AArch64::GPRRegBankID);
260
28.1M
  case AArch64::CCRRegClassID:
261
0
    return getRegBank(AArch64::CCRegBankID);
262
28.1M
  default:
263
0
    llvm_unreachable("Register class not supported");
264
29.9M
  }
265
29.9M
}
266
267
RegisterBankInfo::InstructionMappings
268
AArch64RegisterBankInfo::getInstrAlternativeMappings(
269
97
    const MachineInstr &MI) const {
270
97
  const MachineFunction &MF = *MI.getParent()->getParent();
271
97
  const TargetSubtargetInfo &STI = MF.getSubtarget();
272
97
  const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
273
97
  const MachineRegisterInfo &MRI = MF.getRegInfo();
274
97
275
97
  switch (MI.getOpcode()) {
276
97
  case TargetOpcode::G_OR: {
277
3
    // 32 and 64-bit or can be mapped on either FPR or
278
3
    // GPR for the same cost.
279
3
    unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
280
3
    if (Size != 32 && Size != 64)
281
0
      break;
282
3
283
3
    // If the instruction has any implicit-defs or uses,
284
3
    // do not mess with it.
285
3
    if (MI.getNumOperands() != 3)
286
0
      break;
287
3
    InstructionMappings AltMappings;
288
3
    const InstructionMapping &GPRMapping = getInstructionMapping(
289
3
        /*ID*/ 1, /*Cost*/ 1, getValueMapping(PMI_FirstGPR, Size),
290
3
        /*NumOperands*/ 3);
291
3
    const InstructionMapping &FPRMapping = getInstructionMapping(
292
3
        /*ID*/ 2, /*Cost*/ 1, getValueMapping(PMI_FirstFPR, Size),
293
3
        /*NumOperands*/ 3);
294
3
295
3
    AltMappings.push_back(&GPRMapping);
296
3
    AltMappings.push_back(&FPRMapping);
297
3
    return AltMappings;
298
3
  }
299
12
  case TargetOpcode::G_BITCAST: {
300
12
    unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
301
12
    if (Size != 32 && 
Size != 648
)
302
2
      break;
303
10
304
10
    // If the instruction has any implicit-defs or uses,
305
10
    // do not mess with it.
306
10
    if (MI.getNumOperands() != 2)
307
0
      break;
308
10
309
10
    InstructionMappings AltMappings;
310
10
    const InstructionMapping &GPRMapping = getInstructionMapping(
311
10
        /*ID*/ 1, /*Cost*/ 1,
312
10
        getCopyMapping(AArch64::GPRRegBankID, AArch64::GPRRegBankID, Size),
313
10
        /*NumOperands*/ 2);
314
10
    const InstructionMapping &FPRMapping = getInstructionMapping(
315
10
        /*ID*/ 2, /*Cost*/ 1,
316
10
        getCopyMapping(AArch64::FPRRegBankID, AArch64::FPRRegBankID, Size),
317
10
        /*NumOperands*/ 2);
318
10
    const InstructionMapping &GPRToFPRMapping = getInstructionMapping(
319
10
        /*ID*/ 3,
320
10
        /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
321
10
        getCopyMapping(AArch64::FPRRegBankID, AArch64::GPRRegBankID, Size),
322
10
        /*NumOperands*/ 2);
323
10
    const InstructionMapping &FPRToGPRMapping = getInstructionMapping(
324
10
        /*ID*/ 3,
325
10
        /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
326
10
        getCopyMapping(AArch64::GPRRegBankID, AArch64::FPRRegBankID, Size),
327
10
        /*NumOperands*/ 2);
328
10
329
10
    AltMappings.push_back(&GPRMapping);
330
10
    AltMappings.push_back(&FPRMapping);
331
10
    AltMappings.push_back(&GPRToFPRMapping);
332
10
    AltMappings.push_back(&FPRToGPRMapping);
333
10
    return AltMappings;
334
10
  }
335
10
  case TargetOpcode::G_LOAD: {
336
3
    unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
337
3
    if (Size != 64)
338
1
      break;
339
2
340
2
    // If the instruction has any implicit-defs or uses,
341
2
    // do not mess with it.
342
2
    if (MI.getNumOperands() != 2)
343
0
      break;
344
2
345
2
    InstructionMappings AltMappings;
346
2
    const InstructionMapping &GPRMapping = getInstructionMapping(
347
2
        /*ID*/ 1, /*Cost*/ 1,
348
2
        getOperandsMapping({getValueMapping(PMI_FirstGPR, Size),
349
2
                            // Addresses are GPR 64-bit.
350
2
                            getValueMapping(PMI_FirstGPR, 64)}),
351
2
        /*NumOperands*/ 2);
352
2
    const InstructionMapping &FPRMapping = getInstructionMapping(
353
2
        /*ID*/ 2, /*Cost*/ 1,
354
2
        getOperandsMapping({getValueMapping(PMI_FirstFPR, Size),
355
2
                            // Addresses are GPR 64-bit.
356
2
                            getValueMapping(PMI_FirstGPR, 64)}),
357
2
        /*NumOperands*/ 2);
358
2
359
2
    AltMappings.push_back(&GPRMapping);
360
2
    AltMappings.push_back(&FPRMapping);
361
2
    return AltMappings;
362
2
  }
363
79
  default:
364
79
    break;
365
82
  }
366
82
  return RegisterBankInfo::getInstrAlternativeMappings(MI);
367
82
}
368
369
void AArch64RegisterBankInfo::applyMappingImpl(
370
10
    const OperandsMapper &OpdMapper) const {
371
10
  switch (OpdMapper.getMI().getOpcode()) {
372
10
  case TargetOpcode::G_OR:
373
10
  case TargetOpcode::G_BITCAST:
374
10
  case TargetOpcode::G_LOAD:
375
10
    // Those ID must match getInstrAlternativeMappings.
376
10
    assert((OpdMapper.getInstrMapping().getID() >= 1 &&
377
10
            OpdMapper.getInstrMapping().getID() <= 4) &&
378
10
           "Don't know how to handle that ID");
379
10
    return applyDefaultMapping(OpdMapper);
380
10
  default:
381
0
    llvm_unreachable("Don't know how to handle that operation");
382
10
  }
383
10
}
384
385
/// Returns whether opcode \p Opc is a pre-isel generic floating-point opcode,
386
/// having only floating-point operands.
387
19.4M
static bool isPreISelGenericFloatingPointOpcode(unsigned Opc) {
388
19.4M
  switch (Opc) {
389
19.4M
  case TargetOpcode::G_FADD:
390
200k
  case TargetOpcode::G_FSUB:
391
200k
  case TargetOpcode::G_FMUL:
392
200k
  case TargetOpcode::G_FMA:
393
200k
  case TargetOpcode::G_FDIV:
394
200k
  case TargetOpcode::G_FCONSTANT:
395
200k
  case TargetOpcode::G_FPEXT:
396
200k
  case TargetOpcode::G_FPTRUNC:
397
200k
  case TargetOpcode::G_FCEIL:
398
200k
  case TargetOpcode::G_FFLOOR:
399
200k
  case TargetOpcode::G_FNEARBYINT:
400
200k
  case TargetOpcode::G_FNEG:
401
200k
  case TargetOpcode::G_FCOS:
402
200k
  case TargetOpcode::G_FSIN:
403
200k
  case TargetOpcode::G_FLOG10:
404
200k
  case TargetOpcode::G_FLOG:
405
200k
  case TargetOpcode::G_FLOG2:
406
200k
  case TargetOpcode::G_FSQRT:
407
200k
  case TargetOpcode::G_FABS:
408
200k
  case TargetOpcode::G_FEXP:
409
200k
  case TargetOpcode::G_FRINT:
410
200k
  case TargetOpcode::G_INTRINSIC_TRUNC:
411
200k
  case TargetOpcode::G_INTRINSIC_ROUND:
412
200k
    return true;
413
19.2M
  }
414
19.2M
  return false;
415
19.2M
}
416
417
const RegisterBankInfo::InstructionMapping &
418
AArch64RegisterBankInfo::getSameKindOfOperandsMapping(
419
2.64M
    const MachineInstr &MI) const {
420
2.64M
  const unsigned Opc = MI.getOpcode();
421
2.64M
  const MachineFunction &MF = *MI.getParent()->getParent();
422
2.64M
  const MachineRegisterInfo &MRI = MF.getRegInfo();
423
2.64M
424
2.64M
  unsigned NumOperands = MI.getNumOperands();
425
2.64M
  assert(NumOperands <= 3 &&
426
2.64M
         "This code is for instructions with 3 or less operands");
427
2.64M
428
2.64M
  LLT Ty = MRI.getType(MI.getOperand(0).getReg());
429
2.64M
  unsigned Size = Ty.getSizeInBits();
430
2.64M
  bool IsFPR = Ty.isVector() || 
isPreISelGenericFloatingPointOpcode(Opc)2.59M
;
431
2.64M
432
2.64M
  PartialMappingIdx RBIdx = IsFPR ? 
PMI_FirstFPR151k
:
PMI_FirstGPR2.49M
;
433
2.64M
434
#ifndef NDEBUG
435
  // Make sure all the operands are using similar size and type.
436
  // Should probably be checked by the machine verifier.
437
  // This code won't catch cases where the number of lanes is
438
  // different between the operands.
439
  // If we want to go to that level of details, it is probably
440
  // best to check that the types are the same, period.
441
  // Currently, we just check that the register banks are the same
442
  // for each types.
443
  for (unsigned Idx = 1; Idx != NumOperands; ++Idx) {
444
    LLT OpTy = MRI.getType(MI.getOperand(Idx).getReg());
445
    assert(
446
        AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(
447
            RBIdx, OpTy.getSizeInBits()) ==
448
            AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(RBIdx, Size) &&
449
        "Operand has incompatible size");
450
    bool OpIsFPR = OpTy.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
451
    (void)OpIsFPR;
452
    assert(IsFPR == OpIsFPR && "Operand has incompatible type");
453
  }
454
#endif // End NDEBUG.
455
456
2.64M
  return getInstructionMapping(DefaultMappingID, 1,
457
2.64M
                               getValueMapping(RBIdx, Size), NumOperands);
458
2.64M
}
459
460
bool AArch64RegisterBankInfo::hasFPConstraints(
461
    const MachineInstr &MI, const MachineRegisterInfo &MRI,
462
2.55M
    const TargetRegisterInfo &TRI) const {
463
2.55M
  unsigned Op = MI.getOpcode();
464
2.55M
465
2.55M
  // Do we have an explicit floating point instruction?
466
2.55M
  if (isPreISelGenericFloatingPointOpcode(Op))
467
51.9k
    return true;
468
2.50M
469
2.50M
  // No. Check if we have a copy-like instruction. If we do, then we could
470
2.50M
  // still be fed by floating point instructions.
471
2.50M
  if (Op != TargetOpcode::COPY && 
!MI.isPHI()2.19M
)
472
2.02M
    return false;
473
480k
474
480k
  // MI is copy-like. Return true if it outputs an FPR.
475
480k
  return getRegBank(MI.getOperand(0).getReg(), MRI, TRI) ==
476
480k
         &AArch64::FPRRegBank;
477
480k
}
478
479
bool AArch64RegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
480
                                         const MachineRegisterInfo &MRI,
481
1.71M
                                         const TargetRegisterInfo &TRI) const {
482
1.71M
  switch (MI.getOpcode()) {
483
1.71M
  case TargetOpcode::G_FPTOSI:
484
4.06k
  case TargetOpcode::G_FPTOUI:
485
4.06k
  case TargetOpcode::G_FCMP:
486
4.06k
    return true;
487
1.70M
  default:
488
1.70M
    break;
489
1.70M
  }
490
1.70M
  return hasFPConstraints(MI, MRI, TRI);
491
1.70M
}
492
493
bool AArch64RegisterBankInfo::onlyDefinesFP(
494
    const MachineInstr &MI, const MachineRegisterInfo &MRI,
495
847k
    const TargetRegisterInfo &TRI) const {
496
847k
  switch (MI.getOpcode()) {
497
847k
  case TargetOpcode::G_SITOFP:
498
2.33k
  case TargetOpcode::G_UITOFP:
499
2.33k
  case TargetOpcode::G_EXTRACT_VECTOR_ELT:
500
2.33k
  case TargetOpcode::G_INSERT_VECTOR_ELT:
501
2.33k
    return true;
502
844k
  default:
503
844k
    break;
504
844k
  }
505
844k
  return hasFPConstraints(MI, MRI, TRI);
506
844k
}
507
508
const RegisterBankInfo::InstructionMapping &
509
16.2M
AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
510
16.2M
  const unsigned Opc = MI.getOpcode();
511
16.2M
512
16.2M
  // Try the default logic for non-generic instructions that are either copies
513
16.2M
  // or already have some operands assigned to banks.
514
16.2M
  if ((Opc != TargetOpcode::COPY && 
!isPreISelGenericOpcode(Opc)12.1M
) ||
515
16.2M
      
Opc == TargetOpcode::G_PHI16.1M
) {
516
538k
    const RegisterBankInfo::InstructionMapping &Mapping =
517
538k
        getInstrMappingImpl(MI);
518
538k
    if (Mapping.isValid())
519
538k
      return Mapping;
520
15.7M
  }
521
15.7M
522
15.7M
  const MachineFunction &MF = *MI.getParent()->getParent();
523
15.7M
  const MachineRegisterInfo &MRI = MF.getRegInfo();
524
15.7M
  const TargetSubtargetInfo &STI = MF.getSubtarget();
525
15.7M
  const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
526
15.7M
527
15.7M
  switch (Opc) {
528
15.7M
    // G_{F|S|U}REM are not listed because they are not legal.
529
15.7M
    // Arithmetic ops.
530
15.7M
  case TargetOpcode::G_ADD:
531
2.53M
  case TargetOpcode::G_SUB:
532
2.53M
  case TargetOpcode::G_GEP:
533
2.53M
  case TargetOpcode::G_MUL:
534
2.53M
  case TargetOpcode::G_SDIV:
535
2.53M
  case TargetOpcode::G_UDIV:
536
2.53M
    // Bitwise ops.
537
2.53M
  case TargetOpcode::G_AND:
538
2.53M
  case TargetOpcode::G_OR:
539
2.53M
  case TargetOpcode::G_XOR:
540
2.53M
    // Floating point ops.
541
2.53M
  case TargetOpcode::G_FADD:
542
2.53M
  case TargetOpcode::G_FSUB:
543
2.53M
  case TargetOpcode::G_FMUL:
544
2.53M
  case TargetOpcode::G_FDIV:
545
2.53M
    return getSameKindOfOperandsMapping(MI);
546
2.53M
  case TargetOpcode::G_FPEXT: {
547
12.3k
    LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
548
12.3k
    LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
549
12.3k
    return getInstructionMapping(
550
12.3k
        DefaultMappingID, /*Cost*/ 1,
551
12.3k
        getFPExtMapping(DstTy.getSizeInBits(), SrcTy.getSizeInBits()),
552
12.3k
        /*NumOperands*/ 2);
553
2.53M
  }
554
2.53M
    // Shifts.
555
2.53M
  case TargetOpcode::G_SHL:
556
125k
  case TargetOpcode::G_LSHR:
557
125k
  case TargetOpcode::G_ASHR: {
558
125k
    LLT ShiftAmtTy = MRI.getType(MI.getOperand(2).getReg());
559
125k
    LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
560
125k
    if (ShiftAmtTy.getSizeInBits() == 64 && 
SrcTy.getSizeInBits() == 3292.2k
)
561
18.2k
      return getInstructionMapping(DefaultMappingID, 1,
562
18.2k
                                   &ValMappings[Shift64Imm], 3);
563
107k
    return getSameKindOfOperandsMapping(MI);
564
107k
  }
565
4.13M
  case TargetOpcode::COPY: {
566
4.13M
    unsigned DstReg = MI.getOperand(0).getReg();
567
4.13M
    unsigned SrcReg = MI.getOperand(1).getReg();
568
4.13M
    // Check if one of the register is not a generic register.
569
4.13M
    if ((TargetRegisterInfo::isPhysicalRegister(DstReg) ||
570
4.13M
         
!MRI.getType(DstReg).isValid()1.37M
) ||
571
4.13M
        
(1.37M
TargetRegisterInfo::isPhysicalRegister(SrcReg)1.37M
||
572
3.95M
         
!MRI.getType(SrcReg).isValid()182k
)) {
573
3.95M
      const RegisterBank *DstRB = getRegBank(DstReg, MRI, TRI);
574
3.95M
      const RegisterBank *SrcRB = getRegBank(SrcReg, MRI, TRI);
575
3.95M
      if (!DstRB)
576
1.18M
        DstRB = SrcRB;
577
2.76M
      else if (!SrcRB)
578
0
        SrcRB = DstRB;
579
3.95M
      // If both RB are null that means both registers are generic.
580
3.95M
      // We shouldn't be here.
581
3.95M
      assert(DstRB && SrcRB && "Both RegBank were nullptr");
582
3.95M
      unsigned Size = getSizeInBits(DstReg, MRI, TRI);
583
3.95M
      return getInstructionMapping(
584
3.95M
          DefaultMappingID, copyCost(*DstRB, *SrcRB, Size),
585
3.95M
          getCopyMapping(DstRB->getID(), SrcRB->getID(), Size),
586
3.95M
          // We only care about the mapping of the destination.
587
3.95M
          /*NumOperands*/ 1);
588
3.95M
    }
589
182k
    // Both registers are generic, use G_BITCAST.
590
182k
    LLVM_FALLTHROUGH;
591
182k
  }
592
183k
  case TargetOpcode::G_BITCAST: {
593
183k
    LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
594
183k
    LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
595
183k
    unsigned Size = DstTy.getSizeInBits();
596
183k
    bool DstIsGPR = !DstTy.isVector() && 
DstTy.getSizeInBits() <= 64182k
;
597
183k
    bool SrcIsGPR = !SrcTy.isVector() && 
SrcTy.getSizeInBits() <= 64182k
;
598
183k
    const RegisterBank &DstRB =
599
183k
        DstIsGPR ? 
AArch64::GPRRegBank182k
:
AArch64::FPRRegBank938
;
600
183k
    const RegisterBank &SrcRB =
601
183k
        SrcIsGPR ? 
AArch64::GPRRegBank182k
:
AArch64::FPRRegBank1.27k
;
602
183k
    return getInstructionMapping(
603
183k
        DefaultMappingID, copyCost(DstRB, SrcRB, Size),
604
183k
        getCopyMapping(DstRB.getID(), SrcRB.getID(), Size),
605
183k
        // We only care about the mapping of the destination for COPY.
606
183k
        /*NumOperands*/ Opc == TargetOpcode::G_BITCAST ? 
21.22k
:
1182k
);
607
182k
  }
608
8.90M
  default:
609
8.90M
    break;
610
8.90M
  }
611
8.90M
612
8.90M
  unsigned NumOperands = MI.getNumOperands();
613
8.90M
614
8.90M
  // Track the size and bank of each register.  We don't do partial mappings.
615
8.90M
  SmallVector<unsigned, 4> OpSize(NumOperands);
616
8.90M
  SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
617
28.6M
  for (unsigned Idx = 0; Idx < NumOperands; 
++Idx19.6M
) {
618
19.6M
    auto &MO = MI.getOperand(Idx);
619
19.6M
    if (!MO.isReg() || 
!MO.getReg()14.4M
)
620
5.20M
      continue;
621
14.4M
622
14.4M
    LLT Ty = MRI.getType(MO.getReg());
623
14.4M
    OpSize[Idx] = Ty.getSizeInBits();
624
14.4M
625
14.4M
    // As a top-level guess, vectors go in FPRs, scalars and pointers in GPRs.
626
14.4M
    // For floating-point instructions, scalars go in FPRs.
627
14.4M
    if (Ty.isVector() || 
isPreISelGenericFloatingPointOpcode(Opc)14.2M
||
628
14.4M
        
Ty.getSizeInBits() > 6414.2M
)
629
284k
      OpRegBankIdx[Idx] = PMI_FirstFPR;
630
14.2M
    else
631
14.2M
      OpRegBankIdx[Idx] = PMI_FirstGPR;
632
14.4M
  }
633
8.90M
634
8.90M
  unsigned Cost = 1;
635
8.90M
  // Some of the floating-point instructions have mixed GPR and FPR operands:
636
8.90M
  // fine-tune the computed mapping.
637
8.90M
  switch (Opc) {
638
8.90M
  case TargetOpcode::G_TRUNC: {
639
1.09M
    LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
640
1.09M
    if (!SrcTy.isVector() && 
SrcTy.getSizeInBits() == 1281.09M
)
641
2
      OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR};
642
1.09M
    break;
643
8.90M
  }
644
8.90M
  case TargetOpcode::G_SITOFP:
645
33.5k
  case TargetOpcode::G_UITOFP:
646
33.5k
    if (MRI.getType(MI.getOperand(0).getReg()).isVector())
647
10.9k
      break;
648
22.5k
    OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR};
649
22.5k
    break;
650
22.5k
  case TargetOpcode::G_FPTOSI:
651
4.99k
  case TargetOpcode::G_FPTOUI:
652
4.99k
    if (MRI.getType(MI.getOperand(0).getReg()).isVector())
653
63
      break;
654
4.93k
    OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR};
655
4.93k
    break;
656
15.9k
  case TargetOpcode::G_FCMP:
657
15.9k
    OpRegBankIdx = {PMI_FirstGPR,
658
15.9k
                    /* Predicate */ PMI_None, PMI_FirstFPR, PMI_FirstFPR};
659
15.9k
    break;
660
4.93k
  case TargetOpcode::G_BITCAST:
661
0
    // This is going to be a cross register bank copy and this is expensive.
662
0
    if (OpRegBankIdx[0] != OpRegBankIdx[1])
663
0
      Cost = copyCost(
664
0
          *AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[0]].RegBank,
665
0
          *AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[1]].RegBank,
666
0
          OpSize[0]);
667
0
    break;
668
1.04M
  case TargetOpcode::G_LOAD:
669
1.04M
    // Loading in vector unit is slightly more expensive.
670
1.04M
    // This is actually only true for the LD1R and co instructions,
671
1.04M
    // but anyway for the fast mode this number does not matter and
672
1.04M
    // for the greedy mode the cost of the cross bank copy will
673
1.04M
    // offset this number.
674
1.04M
    // FIXME: Should be derived from the scheduling model.
675
1.04M
    if (OpRegBankIdx[0] != PMI_FirstGPR)
676
10.8k
      Cost = 2;
677
1.03M
    else
678
1.03M
      // Check if that load feeds fp instructions.
679
1.03M
      // In that case, we want the default mapping to be on FPR
680
1.03M
      // instead of blind map every scalar to GPR.
681
1.03M
      for (const MachineInstr &UseMI :
682
1.56M
           MRI.use_instructions(MI.getOperand(0).getReg())) {
683
1.56M
        // If we have at least one direct use in a FP instruction,
684
1.56M
        // assume this was a floating point load in the IR.
685
1.56M
        // If it was not, we would have had a bitcast before
686
1.56M
        // reaching that instruction.
687
1.56M
        if (onlyUsesFP(UseMI, MRI, TRI)) {
688
32.4k
          OpRegBankIdx[0] = PMI_FirstFPR;
689
32.4k
          break;
690
32.4k
        }
691
1.56M
      }
692
1.04M
    break;
693
805k
  case TargetOpcode::G_STORE:
694
805k
    // Check if that store is fed by fp instructions.
695
805k
    if (OpRegBankIdx[0] == PMI_FirstGPR) {
696
704k
      unsigned VReg = MI.getOperand(0).getReg();
697
704k
      if (!VReg)
698
0
        break;
699
704k
      MachineInstr *DefMI = MRI.getVRegDef(VReg);
700
704k
      if (onlyDefinesFP(*DefMI, MRI, TRI))
701
27.9k
        OpRegBankIdx[0] = PMI_FirstFPR;
702
704k
      break;
703
704k
    }
704
101k
    break;
705
101k
  case TargetOpcode::G_SELECT: {
706
74.9k
    // If the destination is FPR, preserve that.
707
74.9k
    if (OpRegBankIdx[0] != PMI_FirstGPR)
708
0
      break;
709
74.9k
710
74.9k
    // If we're taking in vectors, we have no choice but to put everything on
711
74.9k
    // FPRs, except for the condition. The condition must always be on a GPR.
712
74.9k
    LLT SrcTy = MRI.getType(MI.getOperand(2).getReg());
713
74.9k
    if (SrcTy.isVector()) {
714
0
      OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR, PMI_FirstFPR, PMI_FirstFPR};
715
0
      break;
716
0
    }
717
74.9k
718
74.9k
    // Try to minimize the number of copies. If we have more floating point
719
74.9k
    // constrained values than not, then we'll put everything on FPR. Otherwise,
720
74.9k
    // everything has to be on GPR.
721
74.9k
    unsigned NumFP = 0;
722
74.9k
723
74.9k
    // Check if the uses of the result always produce floating point values.
724
74.9k
    //
725
74.9k
    // For example:
726
74.9k
    //
727
74.9k
    // %z = G_SELECT %cond %x %y
728
74.9k
    // fpr = G_FOO %z ...
729
74.9k
    if (any_of(
730
74.9k
            MRI.use_instructions(MI.getOperand(0).getReg()),
731
151k
            [&](MachineInstr &MI) { return onlyUsesFP(MI, MRI, TRI); }))
732
3.39k
      ++NumFP;
733
74.9k
734
74.9k
    // Check if the defs of the source values always produce floating point
735
74.9k
    // values.
736
74.9k
    //
737
74.9k
    // For example:
738
74.9k
    //
739
74.9k
    // %x = G_SOMETHING_ALWAYS_FLOAT %a ...
740
74.9k
    // %z = G_SELECT %cond %x %y
741
74.9k
    //
742
74.9k
    // Also check whether or not the sources have already been decided to be
743
74.9k
    // FPR. Keep track of this.
744
74.9k
    //
745
74.9k
    // This doesn't check the condition, since it's just whatever is in NZCV.
746
74.9k
    // This isn't passed explicitly in a register to fcsel/csel.
747
224k
    for (unsigned Idx = 2; Idx < 4; 
++Idx149k
) {
748
149k
      unsigned VReg = MI.getOperand(Idx).getReg();
749
149k
      MachineInstr *DefMI = MRI.getVRegDef(VReg);
750
149k
      if (getRegBank(VReg, MRI, TRI) == &AArch64::FPRRegBank ||
751
149k
          
onlyDefinesFP(*DefMI, MRI, TRI)142k
)
752
7.48k
        ++NumFP;
753
149k
    }
754
74.9k
755
74.9k
    // If we have more FP constraints than not, then move everything over to
756
74.9k
    // FPR.
757
74.9k
    if (NumFP >= 2)
758
3.75k
      OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR, PMI_FirstFPR, PMI_FirstFPR};
759
74.9k
760
74.9k
    break;
761
74.9k
  }
762
74.9k
  case TargetOpcode::G_UNMERGE_VALUES: {
763
150
    // If the first operand belongs to a FPR register bank, then make sure that
764
150
    // we preserve that.
765
150
    if (OpRegBankIdx[0] != PMI_FirstGPR)
766
0
      break;
767
150
768
150
    LLT SrcTy = MRI.getType(MI.getOperand(MI.getNumOperands()-1).getReg());
769
150
    // UNMERGE into scalars from a vector should always use FPR.
770
150
    // Likewise if any of the uses are FP instructions.
771
150
    if (SrcTy.isVector() ||
772
150
        any_of(MRI.use_instructions(MI.getOperand(0).getReg()),
773
150
               [&](MachineInstr &MI) 
{ return onlyUsesFP(MI, MRI, TRI); }1
)) {
774
150
      // Set the register bank of every operand to FPR.
775
150
      for (unsigned Idx = 0, NumOperands = MI.getNumOperands();
776
890
           Idx < NumOperands; 
++Idx740
)
777
740
        OpRegBankIdx[Idx] = PMI_FirstFPR;
778
150
    }
779
150
    break;
780
150
  }
781
2.87k
  case TargetOpcode::G_EXTRACT_VECTOR_ELT:
782
2.87k
    // Destination and source need to be FPRs.
783
2.87k
    OpRegBankIdx[0] = PMI_FirstFPR;
784
2.87k
    OpRegBankIdx[1] = PMI_FirstFPR;
785
2.87k
786
2.87k
    // Index needs to be a GPR.
787
2.87k
    OpRegBankIdx[2] = PMI_FirstGPR;
788
2.87k
    break;
789
9.77k
  case TargetOpcode::G_INSERT_VECTOR_ELT:
790
9.77k
    OpRegBankIdx[0] = PMI_FirstFPR;
791
9.77k
    OpRegBankIdx[1] = PMI_FirstFPR;
792
9.77k
793
9.77k
    // The element may be either a GPR or FPR. Preserve that behaviour.
794
9.77k
    if (getRegBank(MI.getOperand(2).getReg(), MRI, TRI) == &AArch64::FPRRegBank)
795
7.92k
      OpRegBankIdx[2] = PMI_FirstFPR;
796
1.85k
    else
797
1.85k
      OpRegBankIdx[2] = PMI_FirstGPR;
798
9.77k
799
9.77k
    // Index needs to be a GPR.
800
9.77k
    OpRegBankIdx[3] = PMI_FirstGPR;
801
9.77k
    break;
802
150
  case TargetOpcode::G_EXTRACT: {
803
5
    // For s128 sources we have to use fpr.
804
5
    LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
805
5
    if (SrcTy.getSizeInBits() == 128) {
806
5
      OpRegBankIdx[0] = PMI_FirstFPR;
807
5
      OpRegBankIdx[1] = PMI_FirstFPR;
808
5
    }
809
5
    break;
810
150
  }
811
23.8k
  case TargetOpcode::G_BUILD_VECTOR:
812
23.8k
    // If the first source operand belongs to a FPR register bank, then make
813
23.8k
    // sure that we preserve that.
814
23.8k
    if (OpRegBankIdx[1] != PMI_FirstGPR)
815
0
      break;
816
23.8k
    unsigned VReg = MI.getOperand(1).getReg();
817
23.8k
    if (!VReg)
818
0
      break;
819
23.8k
820
23.8k
    // Get the instruction that defined the source operand reg, and check if
821
23.8k
    // it's a floating point operation. Or, if it's a type like s16 which
822
23.8k
    // doesn't have a exact size gpr register class.
823
23.8k
    MachineInstr *DefMI = MRI.getVRegDef(VReg);
824
23.8k
    unsigned DefOpc = DefMI->getOpcode();
825
23.8k
    const LLT SrcTy = MRI.getType(VReg);
826
23.8k
    if (isPreISelGenericFloatingPointOpcode(DefOpc) ||
827
23.8k
        
SrcTy.getSizeInBits() < 3220.0k
) {
828
4.51k
      // Have a floating point op.
829
4.51k
      // Make sure every operand gets mapped to a FPR register class.
830
4.51k
      unsigned NumOperands = MI.getNumOperands();
831
25.5k
      for (unsigned Idx = 0; Idx < NumOperands; 
++Idx21.0k
)
832
21.0k
        OpRegBankIdx[Idx] = PMI_FirstFPR;
833
4.51k
    }
834
23.8k
    break;
835
8.90M
  }
836
8.90M
837
8.90M
  // Finally construct the computed mapping.
838
8.90M
  SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
839
28.6M
  for (unsigned Idx = 0; Idx < NumOperands; 
++Idx19.6M
) {
840
19.6M
    if (MI.getOperand(Idx).isReg() && 
MI.getOperand(Idx).getReg()14.4M
) {
841
14.4M
      auto Mapping = getValueMapping(OpRegBankIdx[Idx], OpSize[Idx]);
842
14.4M
      if (!Mapping->isValid())
843
0
        return getInvalidInstructionMapping();
844
14.4M
845
14.4M
      OpdsMapping[Idx] = Mapping;
846
14.4M
    }
847
19.6M
  }
848
8.90M
849
8.90M
  return getInstructionMapping(DefaultMappingID, Cost,
850
8.90M
                               getOperandsMapping(OpdsMapping), NumOperands);
851
8.90M
}