Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- AArch64RegisterBankInfo.cpp ----------------------------------------===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
/// \file
10
/// This file implements the targeting of the RegisterBankInfo class for
11
/// AArch64.
12
/// \todo This should be generated by TableGen.
13
//===----------------------------------------------------------------------===//
14
15
#include "AArch64RegisterBankInfo.h"
16
#include "AArch64InstrInfo.h"
17
#include "llvm/ADT/SmallVector.h"
18
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
19
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
20
#include "llvm/CodeGen/LowLevelType.h"
21
#include "llvm/CodeGen/MachineFunction.h"
22
#include "llvm/CodeGen/MachineInstr.h"
23
#include "llvm/CodeGen/MachineOperand.h"
24
#include "llvm/CodeGen/MachineRegisterInfo.h"
25
#include "llvm/Support/ErrorHandling.h"
26
#include "llvm/Target/TargetOpcodes.h"
27
#include "llvm/Target/TargetRegisterInfo.h"
28
#include "llvm/Target/TargetSubtargetInfo.h"
29
#include <algorithm>
30
#include <cassert>
31
32
#define GET_TARGET_REGBANK_IMPL
33
#include "AArch64GenRegisterBank.inc"
34
35
// This file will be TableGen'ed at some point.
36
#include "AArch64GenRegisterBankInfo.def"
37
38
using namespace llvm;
39
40
AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
41
13.9k
    : AArch64GenRegisterBankInfo() {
42
13.9k
  static bool AlreadyInit = false;
43
13.9k
  // We have only one set of register banks, whatever the subtarget
44
13.9k
  // is. Therefore, the initialization of the RegBanks table should be
45
13.9k
  // done only once. Indeed the table of all register banks
46
13.9k
  // (AArch64::RegBanks) is unique in the compiler. At some point, it
47
13.9k
  // will get tablegen'ed and the whole constructor becomes empty.
48
13.9k
  if (AlreadyInit)
49
10
    return;
50
13.9k
  AlreadyInit = true;
51
13.9k
52
13.9k
  const RegisterBank &RBGPR = getRegBank(AArch64::GPRRegBankID);
53
13.9k
  (void)RBGPR;
54
13.9k
  assert(&AArch64::GPRRegBank == &RBGPR &&
55
13.9k
         "The order in RegBanks is messed up");
56
13.9k
57
13.9k
  const RegisterBank &RBFPR = getRegBank(AArch64::FPRRegBankID);
58
13.9k
  (void)RBFPR;
59
13.9k
  assert(&AArch64::FPRRegBank == &RBFPR &&
60
13.9k
         "The order in RegBanks is messed up");
61
13.9k
62
13.9k
  const RegisterBank &RBCCR = getRegBank(AArch64::CCRRegBankID);
63
13.9k
  (void)RBCCR;
64
13.9k
  assert(&AArch64::CCRRegBank == &RBCCR &&
65
13.9k
         "The order in RegBanks is messed up");
66
13.9k
67
13.9k
  // The GPR register bank is fully defined by all the registers in
68
13.9k
  // GR64all + its subclasses.
69
13.9k
  assert(RBGPR.covers(*TRI.getRegClass(AArch64::GPR32RegClassID)) &&
70
13.9k
         "Subclass not added?");
71
13.9k
  assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
72
13.9k
73
13.9k
  // The FPR register bank is fully defined by all the registers in
74
13.9k
  // GR64all + its subclasses.
75
13.9k
  assert(RBFPR.covers(*TRI.getRegClass(AArch64::QQRegClassID)) &&
76
13.9k
         "Subclass not added?");
77
13.9k
  assert(RBFPR.covers(*TRI.getRegClass(AArch64::FPR64RegClassID)) &&
78
13.9k
         "Subclass not added?");
79
13.9k
  assert(RBFPR.getSize() == 512 &&
80
13.9k
         "FPRs should hold up to 512-bit via QQQQ sequence");
81
13.9k
82
13.9k
  assert(RBCCR.covers(*TRI.getRegClass(AArch64::CCRRegClassID)) &&
83
13.9k
         "Class not added?");
84
13.9k
  assert(RBCCR.getSize() == 32 && "CCR should hold up to 32-bit");
85
13.9k
86
13.9k
  // Check that the TableGen'ed like file is in sync we our expectations.
87
13.9k
  // First, the Idx.
88
13.9k
  assert(checkPartialMappingIdx(PMI_FirstGPR, PMI_LastGPR,
89
13.9k
                                {PMI_GPR32, PMI_GPR64}) &&
90
13.9k
         "PartialMappingIdx's are incorrectly ordered");
91
13.9k
  assert(checkPartialMappingIdx(
92
13.9k
             PMI_FirstFPR, PMI_LastFPR,
93
13.9k
             {PMI_FPR32, PMI_FPR64, PMI_FPR128, PMI_FPR256, PMI_FPR512}) &&
94
13.9k
         "PartialMappingIdx's are incorrectly ordered");
95
13.9k
// Now, the content.
96
13.9k
// Check partial mapping.
97
13.9k
#define CHECK_PARTIALMAP(Idx, ValStartIdx, ValLength, RB)                      \
98
97.6k
  
do 97.6k
{ \
99
97.6k
    assert(                                                                    \
100
97.6k
        checkPartialMap(PartialMappingIdx::Idx, ValStartIdx, ValLength, RB) && \
101
97.6k
        #Idx " is incorrectly initialized");                                   \
102
97.6k
  } while (false)
103
13.9k
104
13.9k
  CHECK_PARTIALMAP(PMI_GPR32, 0, 32, RBGPR);
105
13.9k
  CHECK_PARTIALMAP(PMI_GPR64, 0, 64, RBGPR);
106
13.9k
  CHECK_PARTIALMAP(PMI_FPR32, 0, 32, RBFPR);
107
13.9k
  CHECK_PARTIALMAP(PMI_FPR64, 0, 64, RBFPR);
108
13.9k
  CHECK_PARTIALMAP(PMI_FPR128, 0, 128, RBFPR);
109
13.9k
  CHECK_PARTIALMAP(PMI_FPR256, 0, 256, RBFPR);
110
13.9k
  CHECK_PARTIALMAP(PMI_FPR512, 0, 512, RBFPR);
111
13.9k
112
13.9k
// Check value mapping.
113
13.9k
#define CHECK_VALUEMAP_IMPL(RBName, Size, Offset)                              \
114
390k
  
do 390k
{ \
115
390k
    assert(checkValueMapImpl(PartialMappingIdx::PMI_##RBName##Size,            \
116
390k
                             PartialMappingIdx::PMI_First##RBName, Size,       \
117
390k
                             Offset) &&                                        \
118
390k
           #RBName #Size " " #Offset " is incorrectly initialized");           \
119
390k
  } while (false)
120
13.9k
121
97.6k
#define CHECK_VALUEMAP(RBName, Size) CHECK_VALUEMAP_IMPL(RBName, Size, 0)
122
13.9k
123
13.9k
  CHECK_VALUEMAP(GPR, 32);
124
13.9k
  CHECK_VALUEMAP(GPR, 64);
125
13.9k
  CHECK_VALUEMAP(FPR, 32);
126
13.9k
  CHECK_VALUEMAP(FPR, 64);
127
13.9k
  CHECK_VALUEMAP(FPR, 128);
128
13.9k
  CHECK_VALUEMAP(FPR, 256);
129
13.9k
  CHECK_VALUEMAP(FPR, 512);
130
13.9k
131
13.9k
// Check the value mapping for 3-operands instructions where all the operands
132
13.9k
// map to the same value mapping.
133
13.9k
#define CHECK_VALUEMAP_3OPS(RBName, Size)                                      \
134
97.6k
  
do 97.6k
{ \
135
97.6k
    CHECK_VALUEMAP_IMPL(RBName, Size, 0);                                      \
136
97.6k
    CHECK_VALUEMAP_IMPL(RBName, Size, 1);                                      \
137
97.6k
    CHECK_VALUEMAP_IMPL(RBName, Size, 2);                                      \
138
97.6k
  } while (false)
139
13.9k
140
13.9k
  CHECK_VALUEMAP_3OPS(GPR, 32);
141
13.9k
  CHECK_VALUEMAP_3OPS(GPR, 64);
142
13.9k
  CHECK_VALUEMAP_3OPS(FPR, 32);
143
13.9k
  CHECK_VALUEMAP_3OPS(FPR, 64);
144
13.9k
  CHECK_VALUEMAP_3OPS(FPR, 128);
145
13.9k
  CHECK_VALUEMAP_3OPS(FPR, 256);
146
13.9k
  CHECK_VALUEMAP_3OPS(FPR, 512);
147
13.9k
148
13.9k
#define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size)                 \
149
111k
  
do 111k
{ \
150
111k
    unsigned PartialMapDstIdx = PMI_##RBNameDst##Size - PMI_Min;               \
151
111k
    unsigned PartialMapSrcIdx = PMI_##RBNameSrc##Size - PMI_Min;               \
152
111k
    (void)PartialMapDstIdx;                                                    \
153
111k
    (void)PartialMapSrcIdx;                                                    \
154
111k
    const ValueMapping *Map = getCopyMapping(                                  \
155
111k
        AArch64::RBNameDst##RegBankID, AArch64::RBNameSrc##RegBankID, Size);  \
156
111k
    (void)Map;                                                                 \
157
111k
    assert(Map[0].BreakDown ==                                                 \
158
111k
               &AArch64GenRegisterBankInfo::PartMappings[PartialMapDstIdx] &&  \
159
111k
           Map[0].NumBreakDowns == 1 && #RBNameDst #Size                       \
160
111k
           " Dst is incorrectly initialized");                                 \
161
111k
    assert(Map[1].BreakDown ==                                                 \
162
111k
               &AArch64GenRegisterBankInfo::PartMappings[PartialMapSrcIdx] &&  \
163
111k
           Map[1].NumBreakDowns == 1 && #RBNameSrc #Size                       \
164
111k
           " Src is incorrectly initialized");                                 \
165
111k
                                                                               \
166
111k
  } while (false)
167
13.9k
168
13.9k
  CHECK_VALUEMAP_CROSSREGCPY(GPR, GPR, 32);
169
13.9k
  CHECK_VALUEMAP_CROSSREGCPY(GPR, FPR, 32);
170
13.9k
  CHECK_VALUEMAP_CROSSREGCPY(GPR, GPR, 64);
171
13.9k
  CHECK_VALUEMAP_CROSSREGCPY(GPR, FPR, 64);
172
13.9k
  CHECK_VALUEMAP_CROSSREGCPY(FPR, FPR, 32);
173
13.9k
  CHECK_VALUEMAP_CROSSREGCPY(FPR, GPR, 32);
174
13.9k
  CHECK_VALUEMAP_CROSSREGCPY(FPR, FPR, 64);
175
13.9k
  CHECK_VALUEMAP_CROSSREGCPY(FPR, GPR, 64);
176
13.9k
177
13.9k
  assert(verify(TRI) && "Invalid register bank information");
178
13.9k
}
179
180
unsigned AArch64RegisterBankInfo::copyCost(const RegisterBank &A,
181
                                           const RegisterBank &B,
182
348
                                           unsigned Size) const {
183
348
  // What do we do with different size?
184
348
  // copy are same size.
185
348
  // Will introduce other hooks for different size:
186
348
  // * extract cost.
187
348
  // * build_sequence cost.
188
348
189
348
  // Copy from (resp. to) GPR to (resp. from) FPR involves FMOV.
190
348
  // FIXME: This should be deduced from the scheduling model.
191
348
  if (
&A == &AArch64::GPRRegBank && 348
&B == &AArch64::FPRRegBank318
)
192
348
    // FMOVXDr or FMOVWSr.
193
314
    return 5;
194
34
  
if (34
&A == &AArch64::FPRRegBank && 34
&B == &AArch64::GPRRegBank30
)
195
34
    // FMOVDXr or FMOVSWr.
196
26
    return 4;
197
8
198
8
  return RegisterBankInfo::copyCost(A, B, Size);
199
8
}
200
201
const RegisterBank &AArch64RegisterBankInfo::getRegBankFromRegClass(
202
6.99M
    const TargetRegisterClass &RC) const {
203
6.99M
  switch (RC.getID()) {
204
145k
  case AArch64::FPR8RegClassID:
205
145k
  case AArch64::FPR16RegClassID:
206
145k
  case AArch64::FPR32RegClassID:
207
145k
  case AArch64::FPR64RegClassID:
208
145k
  case AArch64::FPR128RegClassID:
209
145k
  case AArch64::FPR128_loRegClassID:
210
145k
  case AArch64::DDRegClassID:
211
145k
  case AArch64::DDDRegClassID:
212
145k
  case AArch64::DDDDRegClassID:
213
145k
  case AArch64::QQRegClassID:
214
145k
  case AArch64::QQQRegClassID:
215
145k
  case AArch64::QQQQRegClassID:
216
145k
    return getRegBank(AArch64::FPRRegBankID);
217
6.85M
  case AArch64::GPR32commonRegClassID:
218
6.85M
  case AArch64::GPR32RegClassID:
219
6.85M
  case AArch64::GPR32spRegClassID:
220
6.85M
  case AArch64::GPR32sponlyRegClassID:
221
6.85M
  case AArch64::GPR32allRegClassID:
222
6.85M
  case AArch64::GPR64commonRegClassID:
223
6.85M
  case AArch64::GPR64RegClassID:
224
6.85M
  case AArch64::GPR64spRegClassID:
225
6.85M
  case AArch64::GPR64sponlyRegClassID:
226
6.85M
  case AArch64::GPR64allRegClassID:
227
6.85M
  case AArch64::tcGPR64RegClassID:
228
6.85M
  case AArch64::WSeqPairsClassRegClassID:
229
6.85M
  case AArch64::XSeqPairsClassRegClassID:
230
6.85M
    return getRegBank(AArch64::GPRRegBankID);
231
0
  case AArch64::CCRRegClassID:
232
0
    return getRegBank(AArch64::CCRRegBankID);
233
0
  default:
234
0
    llvm_unreachable("Register class not supported");
235
0
  }
236
0
}
237
238
RegisterBankInfo::InstructionMappings
239
AArch64RegisterBankInfo::getInstrAlternativeMappings(
240
63
    const MachineInstr &MI) const {
241
63
  const MachineFunction &MF = *MI.getParent()->getParent();
242
63
  const TargetSubtargetInfo &STI = MF.getSubtarget();
243
63
  const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
244
63
  const MachineRegisterInfo &MRI = MF.getRegInfo();
245
63
246
63
  switch (MI.getOpcode()) {
247
3
  case TargetOpcode::G_OR: {
248
3
    // 32 and 64-bit or can be mapped on either FPR or
249
3
    // GPR for the same cost.
250
3
    unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
251
3
    if (
Size != 32 && 3
Size != 643
)
252
0
      break;
253
3
254
3
    // If the instruction has any implicit-defs or uses,
255
3
    // do not mess with it.
256
3
    
if (3
MI.getNumOperands() != 33
)
257
0
      break;
258
3
    InstructionMappings AltMappings;
259
3
    const InstructionMapping &GPRMapping = getInstructionMapping(
260
3
        /*ID*/ 1, /*Cost*/ 1, getValueMapping(PMI_FirstGPR, Size),
261
3
        /*NumOperands*/ 3);
262
3
    const InstructionMapping &FPRMapping = getInstructionMapping(
263
3
        /*ID*/ 2, /*Cost*/ 1, getValueMapping(PMI_FirstFPR, Size),
264
3
        /*NumOperands*/ 3);
265
3
266
3
    AltMappings.push_back(&GPRMapping);
267
3
    AltMappings.push_back(&FPRMapping);
268
3
    return AltMappings;
269
3
  }
270
10
  case TargetOpcode::G_BITCAST: {
271
10
    unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
272
10
    if (
Size != 32 && 10
Size != 646
)
273
0
      break;
274
10
275
10
    // If the instruction has any implicit-defs or uses,
276
10
    // do not mess with it.
277
10
    
if (10
MI.getNumOperands() != 210
)
278
0
      break;
279
10
280
10
    InstructionMappings AltMappings;
281
10
    const InstructionMapping &GPRMapping = getInstructionMapping(
282
10
        /*ID*/ 1, /*Cost*/ 1,
283
10
        getCopyMapping(AArch64::GPRRegBankID, AArch64::GPRRegBankID, Size),
284
10
        /*NumOperands*/ 2);
285
10
    const InstructionMapping &FPRMapping = getInstructionMapping(
286
10
        /*ID*/ 2, /*Cost*/ 1,
287
10
        getCopyMapping(AArch64::FPRRegBankID, AArch64::FPRRegBankID, Size),
288
10
        /*NumOperands*/ 2);
289
10
    const InstructionMapping &GPRToFPRMapping = getInstructionMapping(
290
10
        /*ID*/ 3,
291
10
        /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
292
10
        getCopyMapping(AArch64::FPRRegBankID, AArch64::GPRRegBankID, Size),
293
10
        /*NumOperands*/ 2);
294
10
    const InstructionMapping &FPRToGPRMapping = getInstructionMapping(
295
10
        /*ID*/ 3,
296
10
        /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
297
10
        getCopyMapping(AArch64::GPRRegBankID, AArch64::FPRRegBankID, Size),
298
10
        /*NumOperands*/ 2);
299
10
300
10
    AltMappings.push_back(&GPRMapping);
301
10
    AltMappings.push_back(&FPRMapping);
302
10
    AltMappings.push_back(&GPRToFPRMapping);
303
10
    AltMappings.push_back(&FPRToGPRMapping);
304
10
    return AltMappings;
305
10
  }
306
2
  case TargetOpcode::G_LOAD: {
307
2
    unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
308
2
    if (Size != 64)
309
0
      break;
310
2
311
2
    // If the instruction has any implicit-defs or uses,
312
2
    // do not mess with it.
313
2
    
if (2
MI.getNumOperands() != 22
)
314
0
      break;
315
2
316
2
    InstructionMappings AltMappings;
317
2
    const InstructionMapping &GPRMapping = getInstructionMapping(
318
2
        /*ID*/ 1, /*Cost*/ 1,
319
2
        getOperandsMapping({getValueMapping(PMI_FirstGPR, Size),
320
2
                            // Addresses are GPR 64-bit.
321
2
                            getValueMapping(PMI_FirstGPR, 64)}),
322
2
        /*NumOperands*/ 2);
323
2
    const InstructionMapping &FPRMapping = getInstructionMapping(
324
2
        /*ID*/ 2, /*Cost*/ 1,
325
2
        getOperandsMapping({getValueMapping(PMI_FirstFPR, Size),
326
2
                            // Addresses are GPR 64-bit.
327
2
                            getValueMapping(PMI_FirstGPR, 64)}),
328
2
        /*NumOperands*/ 2);
329
2
330
2
    AltMappings.push_back(&GPRMapping);
331
2
    AltMappings.push_back(&FPRMapping);
332
2
    return AltMappings;
333
2
  }
334
48
  default:
335
48
    break;
336
48
  }
337
48
  return RegisterBankInfo::getInstrAlternativeMappings(MI);
338
48
}
339
340
void AArch64RegisterBankInfo::applyMappingImpl(
341
10
    const OperandsMapper &OpdMapper) const {
342
10
  switch (OpdMapper.getMI().getOpcode()) {
343
10
  case TargetOpcode::G_OR:
344
10
  case TargetOpcode::G_BITCAST:
345
10
  case TargetOpcode::G_LOAD:
346
10
    // Those ID must match getInstrAlternativeMappings.
347
10
    assert((OpdMapper.getInstrMapping().getID() >= 1 &&
348
10
            OpdMapper.getInstrMapping().getID() <= 4) &&
349
10
           "Don't know how to handle that ID");
350
10
    return applyDefaultMapping(OpdMapper);
351
0
  default:
352
0
    llvm_unreachable("Don't know how to handle that operation");
353
0
  }
354
0
}
355
356
/// Returns whether opcode \p Opc is a pre-isel generic floating-point opcode,
357
/// having only floating-point operands.
358
7.07M
static bool isPreISelGenericFloatingPointOpcode(unsigned Opc) {
359
7.07M
  switch (Opc) {
360
22.0k
  case TargetOpcode::G_FADD:
361
22.0k
  case TargetOpcode::G_FSUB:
362
22.0k
  case TargetOpcode::G_FMUL:
363
22.0k
  case TargetOpcode::G_FDIV:
364
22.0k
  case TargetOpcode::G_FCONSTANT:
365
22.0k
  case TargetOpcode::G_FPEXT:
366
22.0k
  case TargetOpcode::G_FPTRUNC:
367
22.0k
    return true;
368
7.05M
  }
369
7.05M
  return false;
370
7.05M
}
371
372
const RegisterBankInfo::InstructionMapping &
373
AArch64RegisterBankInfo::getSameKindOfOperandsMapping(
374
826k
    const MachineInstr &MI) const {
375
826k
  const unsigned Opc = MI.getOpcode();
376
826k
  const MachineFunction &MF = *MI.getParent()->getParent();
377
826k
  const MachineRegisterInfo &MRI = MF.getRegInfo();
378
826k
379
826k
  unsigned NumOperands = MI.getNumOperands();
380
826k
  assert(NumOperands <= 3 &&
381
826k
         "This code is for instructions with 3 or less operands");
382
826k
383
826k
  LLT Ty = MRI.getType(MI.getOperand(0).getReg());
384
826k
  unsigned Size = Ty.getSizeInBits();
385
826k
  bool IsFPR = Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
386
826k
387
826k
  PartialMappingIdx RBIdx = IsFPR ? 
PMI_FirstFPR9.80k
:
PMI_FirstGPR816k
;
388
826k
389
#ifndef NDEBUG
390
  // Make sure all the operands are using similar size and type.
391
  // Should probably be checked by the machine verifier.
392
  // This code won't catch cases where the number of lanes is
393
  // different between the operands.
394
  // If we want to go to that level of details, it is probably
395
  // best to check that the types are the same, period.
396
  // Currently, we just check that the register banks are the same
397
  // for each types.
398
  for (unsigned Idx = 1; Idx != NumOperands; ++Idx) {
399
    LLT OpTy = MRI.getType(MI.getOperand(Idx).getReg());
400
    assert(
401
        AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(
402
            RBIdx, OpTy.getSizeInBits()) ==
403
            AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(RBIdx, Size) &&
404
        "Operand has incompatible size");
405
    bool OpIsFPR = OpTy.isVector() || isPreISelGenericFloatingPointOpcode(Opc);
406
    (void)OpIsFPR;
407
    assert(IsFPR == OpIsFPR && "Operand has incompatible type");
408
  }
409
#endif // End NDEBUG.
410
411
826k
  return getInstructionMapping(DefaultMappingID, 1,
412
826k
                               getValueMapping(RBIdx, Size), NumOperands);
413
826k
}
414
415
const RegisterBankInfo::InstructionMapping &
416
7.21M
AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
417
7.21M
  const unsigned Opc = MI.getOpcode();
418
7.21M
  const MachineFunction &MF = *MI.getParent()->getParent();
419
7.21M
  const MachineRegisterInfo &MRI = MF.getRegInfo();
420
7.21M
421
7.21M
  // Try the default logic for non-generic instructions that are either copies
422
7.21M
  // or already have some operands assigned to banks.
423
7.21M
  if (!isPreISelGenericOpcode(Opc) ||
424
7.21M
      
Opc == TargetOpcode::G_PHI4.39M
) {
425
2.91M
    const RegisterBankInfo::InstructionMapping &Mapping =
426
2.91M
        getInstrMappingImpl(MI);
427
2.91M
    if (Mapping.isValid())
428
2.91M
      return Mapping;
429
4.30M
  }
430
4.30M
431
4.30M
  switch (Opc) {
432
4.30M
    // G_{F|S|U}REM are not listed because they are not legal.
433
4.30M
    // Arithmetic ops.
434
826k
  case TargetOpcode::G_ADD:
435
826k
  case TargetOpcode::G_SUB:
436
826k
  case TargetOpcode::G_GEP:
437
826k
  case TargetOpcode::G_MUL:
438
826k
  case TargetOpcode::G_SDIV:
439
826k
  case TargetOpcode::G_UDIV:
440
826k
    // Bitwise ops.
441
826k
  case TargetOpcode::G_AND:
442
826k
  case TargetOpcode::G_OR:
443
826k
  case TargetOpcode::G_XOR:
444
826k
    // Shifts.
445
826k
  case TargetOpcode::G_SHL:
446
826k
  case TargetOpcode::G_LSHR:
447
826k
  case TargetOpcode::G_ASHR:
448
826k
    // Floating point ops.
449
826k
  case TargetOpcode::G_FADD:
450
826k
  case TargetOpcode::G_FSUB:
451
826k
  case TargetOpcode::G_FMUL:
452
826k
  case TargetOpcode::G_FDIV:
453
826k
    return getSameKindOfOperandsMapping(MI);
454
302
  case TargetOpcode::G_BITCAST: {
455
302
    LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
456
302
    LLT SrcTy = MRI.getType(MI.getOperand(1).getReg());
457
302
    unsigned Size = DstTy.getSizeInBits();
458
302
    bool DstIsGPR = !DstTy.isVector();
459
302
    bool SrcIsGPR = !SrcTy.isVector();
460
302
    const RegisterBank &DstRB =
461
302
        DstIsGPR ? 
AArch64::GPRRegBank292
:
AArch64::FPRRegBank10
;
462
302
    const RegisterBank &SrcRB =
463
302
        SrcIsGPR ? 
AArch64::GPRRegBank10
:
AArch64::FPRRegBank292
;
464
302
    return getInstructionMapping(
465
302
        DefaultMappingID, copyCost(DstRB, SrcRB, Size),
466
302
        getCopyMapping(DstRB.getID(), SrcRB.getID(), Size),
467
302
        /*NumOperands*/ 2);
468
826k
  }
469
3.48M
  default:
470
3.48M
    break;
471
3.48M
  }
472
3.48M
473
3.48M
  unsigned NumOperands = MI.getNumOperands();
474
3.48M
475
3.48M
  // Track the size and bank of each register.  We don't do partial mappings.
476
3.48M
  SmallVector<unsigned, 4> OpSize(NumOperands);
477
3.48M
  SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
478
11.0M
  for (unsigned Idx = 0; 
Idx < NumOperands11.0M
;
++Idx7.57M
) {
479
7.57M
    auto &MO = MI.getOperand(Idx);
480
7.57M
    if (
!MO.isReg() || 7.57M
!MO.getReg()5.46M
)
481
2.10M
      continue;
482
5.46M
483
5.46M
    LLT Ty = MRI.getType(MO.getReg());
484
5.46M
    OpSize[Idx] = Ty.getSizeInBits();
485
5.46M
486
5.46M
    // As a top-level guess, vectors go in FPRs, scalars and pointers in GPRs.
487
5.46M
    // For floating-point instructions, scalars go in FPRs.
488
5.46M
    if (
Ty.isVector() || 5.46M
isPreISelGenericFloatingPointOpcode(Opc)5.45M
||
489
5.44M
        Ty.getSizeInBits() > 64)
490
25.2k
      OpRegBankIdx[Idx] = PMI_FirstFPR;
491
5.46M
    else
492
5.44M
      OpRegBankIdx[Idx] = PMI_FirstGPR;
493
7.57M
  }
494
3.48M
495
3.48M
  unsigned Cost = 1;
496
3.48M
  // Some of the floating-point instructions have mixed GPR and FPR operands:
497
3.48M
  // fine-tune the computed mapping.
498
3.48M
  switch (Opc) {
499
1.43k
  case TargetOpcode::G_SITOFP:
500
1.43k
  case TargetOpcode::G_UITOFP:
501
1.43k
    OpRegBankIdx = {PMI_FirstFPR, PMI_FirstGPR};
502
1.43k
    break;
503
630
  case TargetOpcode::G_FPTOSI:
504
630
  case TargetOpcode::G_FPTOUI:
505
630
    OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR};
506
630
    break;
507
1.53k
  case TargetOpcode::G_FCMP:
508
1.53k
    OpRegBankIdx = {PMI_FirstGPR,
509
1.53k
                    /* Predicate */ PMI_None, PMI_FirstFPR, PMI_FirstFPR};
510
1.53k
    break;
511
0
  case TargetOpcode::G_BITCAST:
512
0
    // This is going to be a cross register bank copy and this is expensive.
513
0
    if (OpRegBankIdx[0] != OpRegBankIdx[1])
514
0
      Cost = copyCost(
515
0
          *AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[0]].RegBank,
516
0
          *AArch64GenRegisterBankInfo::PartMappings[OpRegBankIdx[1]].RegBank,
517
0
          OpSize[0]);
518
0
    break;
519
363k
  case TargetOpcode::G_LOAD:
520
363k
    // Loading in vector unit is slightly more expensive.
521
363k
    // This is actually only true for the LD1R and co instructions,
522
363k
    // but anyway for the fast mode this number does not matter and
523
363k
    // for the greedy mode the cost of the cross bank copy will
524
363k
    // offset this number.
525
363k
    // FIXME: Should be derived from the scheduling model.
526
363k
    if (OpRegBankIdx[0] != PMI_FirstGPR)
527
32
      Cost = 2;
528
363k
    else
529
363k
      // Check if that load feeds fp instructions.
530
363k
      // In that case, we want the default mapping to be on FPR
531
363k
      // instead of blind map every scalar to GPR.
532
363k
      for (const MachineInstr &UseMI :
533
363k
           MRI.use_instructions(MI.getOperand(0).getReg()))
534
363k
        // If we have at least one direct use in a FP instruction,
535
363k
        // assume this was a floating point load in the IR.
536
363k
        // If it was not, we would have had a bitcast before
537
363k
        // reaching that instruction.
538
485k
        
if (485k
isPreISelGenericFloatingPointOpcode(UseMI.getOpcode())485k
) {
539
2.82k
          OpRegBankIdx[0] = PMI_FirstFPR;
540
2.82k
          break;
541
2.82k
        }
542
363k
    break;
543
323k
  case TargetOpcode::G_STORE:
544
323k
    // Check if that store is fed by fp instructions.
545
323k
    if (
OpRegBankIdx[0] == PMI_FirstGPR323k
) {
546
315k
      unsigned VReg = MI.getOperand(0).getReg();
547
315k
      if (!VReg)
548
0
        break;
549
315k
      MachineInstr *DefMI = MRI.getVRegDef(VReg);
550
315k
      if (isPreISelGenericFloatingPointOpcode(DefMI->getOpcode()))
551
2.31k
        OpRegBankIdx[0] = PMI_FirstFPR;
552
1.43k
      break;
553
1.43k
    }
554
3.48M
  }
555
3.48M
556
3.48M
  // Finally construct the computed mapping.
557
3.48M
  SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
558
11.0M
  for (unsigned Idx = 0; 
Idx < NumOperands11.0M
;
++Idx7.57M
) {
559
7.57M
    if (
MI.getOperand(Idx).isReg() && 7.57M
MI.getOperand(Idx).getReg()5.46M
) {
560
5.46M
      auto Mapping = getValueMapping(OpRegBankIdx[Idx], OpSize[Idx]);
561
5.46M
      if (!Mapping->isValid())
562
0
        return getInvalidInstructionMapping();
563
5.46M
564
5.46M
      OpdsMapping[Idx] = Mapping;
565
5.46M
    }
566
7.57M
  }
567
3.48M
568
3.48M
  return getInstructionMapping(DefaultMappingID, Cost,
569
3.48M
                               getOperandsMapping(OpdsMapping), NumOperands);
570
7.21M
}