Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- MipsRegisterBankInfo.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
/// \file
9
/// This file implements the targeting of the RegisterBankInfo class for Mips.
10
/// \todo This should be generated by TableGen.
11
//===----------------------------------------------------------------------===//
12
13
#include "MipsRegisterBankInfo.h"
14
#include "MipsInstrInfo.h"
15
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
16
#include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h"
17
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
18
#include "llvm/CodeGen/MachineRegisterInfo.h"
19
20
#define GET_TARGET_REGBANK_IMPL
21
22
#include "MipsGenRegisterBank.inc"
23
24
namespace llvm {
25
namespace Mips {
26
enum PartialMappingIdx {
27
  PMI_GPR,
28
  PMI_SPR,
29
  PMI_DPR,
30
  PMI_Min = PMI_GPR,
31
};
32
33
RegisterBankInfo::PartialMapping PartMappings[]{
34
    {0, 32, GPRBRegBank},
35
    {0, 32, FPRBRegBank},
36
    {0, 64, FPRBRegBank}
37
};
38
39
enum ValueMappingIdx {
40
    InvalidIdx = 0,
41
    GPRIdx = 1,
42
    SPRIdx = 4,
43
    DPRIdx = 7
44
};
45
46
RegisterBankInfo::ValueMapping ValueMappings[] = {
47
    // invalid
48
    {nullptr, 0},
49
    // up to 3 operands in GPRs
50
    {&PartMappings[PMI_GPR - PMI_Min], 1},
51
    {&PartMappings[PMI_GPR - PMI_Min], 1},
52
    {&PartMappings[PMI_GPR - PMI_Min], 1},
53
    // up to 3 ops operands FPRs - single precission
54
    {&PartMappings[PMI_SPR - PMI_Min], 1},
55
    {&PartMappings[PMI_SPR - PMI_Min], 1},
56
    {&PartMappings[PMI_SPR - PMI_Min], 1},
57
    // up to 3 ops operands FPRs - double precission
58
    {&PartMappings[PMI_DPR - PMI_Min], 1},
59
    {&PartMappings[PMI_DPR - PMI_Min], 1},
60
    {&PartMappings[PMI_DPR - PMI_Min], 1}
61
};
62
63
} // end namespace Mips
64
} // end namespace llvm
65
66
using namespace llvm;
67
68
MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI)
69
11.3k
    : MipsGenRegisterBankInfo() {}
70
71
const RegisterBank &MipsRegisterBankInfo::getRegBankFromRegClass(
72
6.62k
    const TargetRegisterClass &RC) const {
73
6.62k
  using namespace Mips;
74
6.62k
75
6.62k
  switch (RC.getID()) {
76
6.62k
  case Mips::GPR32RegClassID:
77
4.78k
  case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID:
78
4.78k
  case Mips::GPRMM16MovePPairFirstRegClassID:
79
4.78k
  case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID:
80
4.78k
  case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID:
81
4.78k
  case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID:
82
4.78k
  case Mips::SP32RegClassID:
83
4.78k
  case Mips::GP32RegClassID:
84
4.78k
    return getRegBank(Mips::GPRBRegBankID);
85
4.78k
  case Mips::FGRCCRegClassID:
86
1.83k
  case Mips::FGR32RegClassID:
87
1.83k
  case Mips::FGR64RegClassID:
88
1.83k
  case Mips::AFGR64RegClassID:
89
1.83k
    return getRegBank(Mips::FPRBRegBankID);
90
1.83k
  default:
91
0
    llvm_unreachable("Register class not supported");
92
6.62k
  }
93
6.62k
}
94
95
// Instructions where all register operands are floating point.
96
625
static bool isFloatingPointOpcode(unsigned Opc) {
97
625
  switch (Opc) {
98
625
  case TargetOpcode::G_FCONSTANT:
99
8
  case TargetOpcode::G_FADD:
100
8
  case TargetOpcode::G_FSUB:
101
8
  case TargetOpcode::G_FMUL:
102
8
  case TargetOpcode::G_FDIV:
103
8
  case TargetOpcode::G_FABS:
104
8
  case TargetOpcode::G_FSQRT:
105
8
  case TargetOpcode::G_FCEIL:
106
8
  case TargetOpcode::G_FFLOOR:
107
8
  case TargetOpcode::G_FPEXT:
108
8
  case TargetOpcode::G_FPTRUNC:
109
8
    return true;
110
617
  default:
111
617
    return false;
112
625
  }
113
625
}
114
115
// Instructions where use operands are floating point registers.
116
// Def operands are general purpose.
117
372
static bool isFloatingPointOpcodeUse(unsigned Opc) {
118
372
  switch (Opc) {
119
372
  case TargetOpcode::G_FPTOSI:
120
0
  case TargetOpcode::G_FPTOUI:
121
0
  case TargetOpcode::G_FCMP:
122
0
  case Mips::MFC1:
123
0
  case Mips::ExtractElementF64:
124
0
  case Mips::ExtractElementF64_64:
125
0
    return true;
126
372
  default:
127
372
    return isFloatingPointOpcode(Opc);
128
372
  }
129
372
}
130
131
// Instructions where def operands are floating point registers.
132
// Use operands are general purpose.
133
253
static bool isFloatingPointOpcodeDef(unsigned Opc) {
134
253
  switch (Opc) {
135
253
  case TargetOpcode::G_SITOFP:
136
0
  case TargetOpcode::G_UITOFP:
137
0
  case Mips::MTC1:
138
0
  case Mips::BuildPairF64:
139
0
  case Mips::BuildPairF64_64:
140
0
    return true;
141
253
  default:
142
253
    return isFloatingPointOpcode(Opc);
143
253
  }
144
253
}
145
146
557
static bool isAmbiguous(unsigned Opc) {
147
557
  switch (Opc) {
148
557
  case TargetOpcode::G_LOAD:
149
502
  case TargetOpcode::G_STORE:
150
502
  case TargetOpcode::G_PHI:
151
502
  case TargetOpcode::G_SELECT:
152
502
    return true;
153
502
  default:
154
55
    return false;
155
557
  }
156
557
}
157
158
void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses(
159
318
    Register Reg, const MachineRegisterInfo &MRI) {
160
318
  assert(!MRI.getType(Reg).isPointer() &&
161
318
         "Pointers are gprb, they should not be considered as ambiguous.\n");
162
429
  for (MachineInstr &UseMI : MRI.use_instructions(Reg)) {
163
429
    MachineInstr *NonCopyInstr = skipCopiesOutgoing(&UseMI);
164
429
    // Copy with many uses.
165
429
    if (NonCopyInstr->getOpcode() == TargetOpcode::COPY &&
166
429
        !TargetRegisterInfo::isPhysicalRegister(
167
56
            NonCopyInstr->getOperand(0).getReg()))
168
2
      addDefUses(NonCopyInstr->getOperand(0).getReg(), MRI);
169
427
    else
170
427
      DefUses.push_back(skipCopiesOutgoing(&UseMI));
171
429
  }
172
318
}
173
174
void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
175
407
    Register Reg, const MachineRegisterInfo &MRI) {
176
407
  assert(!MRI.getType(Reg).isPointer() &&
177
407
         "Pointers are gprb, they should not be considered as ambiguous.\n");
178
407
  MachineInstr *DefMI = MRI.getVRegDef(Reg);
179
407
  UseDefs.push_back(skipCopiesIncoming(DefMI));
180
407
}
181
182
MachineInstr *
183
MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing(
184
856
    MachineInstr *MI) const {
185
856
  const MachineFunction &MF = *MI->getParent()->getParent();
186
856
  const MachineRegisterInfo &MRI = MF.getRegInfo();
187
856
  MachineInstr *Ret = MI;
188
906
  while (Ret->getOpcode() == TargetOpcode::COPY &&
189
906
         
!TargetRegisterInfo::isPhysicalRegister(Ret->getOperand(0).getReg())160
&&
190
906
         
MRI.hasOneUse(Ret->getOperand(0).getReg())52
) {
191
50
    Ret = &(*MRI.use_instr_begin(Ret->getOperand(0).getReg()));
192
50
  }
193
856
  return Ret;
194
856
}
195
196
MachineInstr *
197
MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming(
198
407
    MachineInstr *MI) const {
199
407
  const MachineFunction &MF = *MI->getParent()->getParent();
200
407
  const MachineRegisterInfo &MRI = MF.getRegInfo();
201
407
  MachineInstr *Ret = MI;
202
446
  while (Ret->getOpcode() == TargetOpcode::COPY &&
203
446
         
!TargetRegisterInfo::isPhysicalRegister(Ret->getOperand(1).getReg())77
)
204
39
    Ret = MRI.getVRegDef(Ret->getOperand(1).getReg());
205
407
  return Ret;
206
407
}
207
208
MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
209
417
    const MachineInstr *MI) {
210
417
  assert(isAmbiguous(MI->getOpcode()) &&
211
417
         "Not implemented for non Ambiguous opcode.\n");
212
417
213
417
  const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
214
417
215
417
  if (MI->getOpcode() == TargetOpcode::G_LOAD)
216
171
    addDefUses(MI->getOperand(0).getReg(), MRI);
217
417
218
417
  if (MI->getOpcode() == TargetOpcode::G_STORE)
219
101
    addUseDef(MI->getOperand(0).getReg(), MRI);
220
417
221
417
  if (MI->getOpcode() == TargetOpcode::G_PHI) {
222
79
    addDefUses(MI->getOperand(0).getReg(), MRI);
223
79
224
253
    for (unsigned i = 1; i < MI->getNumOperands(); 
i += 2174
)
225
174
      addUseDef(MI->getOperand(i).getReg(), MRI);
226
79
  }
227
417
228
417
  if (MI->getOpcode() == TargetOpcode::G_SELECT) {
229
66
    addDefUses(MI->getOperand(0).getReg(), MRI);
230
66
231
66
    addUseDef(MI->getOperand(2).getReg(), MRI);
232
66
    addUseDef(MI->getOperand(3).getReg(), MRI);
233
66
  }
234
417
}
235
236
bool MipsRegisterBankInfo::TypeInfoForMF::visit(
237
683
    const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI) {
238
683
  assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n");
239
683
  if (wasVisited(MI))
240
266
    return true; // InstType has already been determined for MI.
241
417
242
417
  startVisit(MI);
243
417
  AmbiguousRegDefUseContainer DefUseContainer(MI);
244
417
245
417
  // Visit instructions where MI's DEF operands are USED.
246
417
  if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true))
247
168
    return true;
248
249
249
249
  // Visit instructions that DEFINE MI's USE operands.
250
249
  if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false))
251
57
    return true;
252
192
253
192
  // All MI's adjacent instructions, are ambiguous.
254
192
  if (!WaitingForTypeOfMI) {
255
28
    // This is chain of ambiguous instructions.
256
28
    setTypes(MI, InstType::Ambiguous);
257
28
    return true;
258
28
  }
259
164
  // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous
260
164
  // instructions or has no other adjacent instructions. Anyway InstType could
261
164
  // not be determined. There could be unexplored path from some of
262
164
  // WaitingForTypeOfMI's adjacent instructions to an instruction with only one
263
164
  // mapping available.
264
164
  // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue,
265
164
  // this way when WaitingForTypeOfMI figures out its InstType same InstType
266
164
  // will be assigned to all instructions in this branch.
267
164
  addToWaitingQueue(WaitingForTypeOfMI, MI);
268
164
  return false;
269
164
}
270
271
bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
272
    const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
273
666
    bool isDefUse) {
274
1.06k
  while (!AdjacentInstrs.empty()) {
275
625
    MachineInstr *AdjMI = AdjacentInstrs.pop_back_val();
276
625
277
625
    if (isDefUse ? 
isFloatingPointOpcodeUse(AdjMI->getOpcode())372
278
625
                 : 
isFloatingPointOpcodeDef(AdjMI->getOpcode())253
) {
279
8
      setTypes(MI, InstType::FloatingPoint);
280
8
      return true;
281
8
    }
282
617
283
617
    // Determine InstType from register bank of phys register that is
284
617
    // 'isDefUse ? def : use' of this copy.
285
617
    if (AdjMI->getOpcode() == TargetOpcode::COPY) {
286
60
      setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 
054
:
16
);
287
60
      return true;
288
60
    }
289
557
290
557
    // Defaults to integer instruction. Includes G_MERGE_VALUES and
291
557
    // G_UNMERGE_VALUES.
292
557
    if (!isAmbiguous(AdjMI->getOpcode())) {
293
55
      setTypes(MI, InstType::Integer);
294
55
      return true;
295
55
    }
296
502
297
502
    // When AdjMI was visited first, MI has to continue to explore remaining
298
502
    // adjacent instructions and determine InstType without visiting AdjMI.
299
502
    if (!wasVisited(AdjMI) ||
300
502
        
getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined280
) {
301
266
      if (visit(AdjMI, MI)) {
302
102
        // InstType is successfully determined and is same as for AdjMI.
303
102
        setTypes(MI, getRecordedTypeForInstr(AdjMI));
304
102
        return true;
305
102
      }
306
266
    }
307
502
  }
308
666
  
return false441
;
309
666
}
310
311
void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr *MI,
312
417
                                                   InstType InstTy) {
313
417
  changeRecordedTypeForInstr(MI, InstTy);
314
417
  for (const MachineInstr *WaitingInstr : getWaitingQueueFor(MI)) {
315
164
    setTypes(WaitingInstr, InstTy);
316
164
  }
317
417
}
318
319
void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister(
320
60
    const MachineInstr *MI, const MachineInstr *CopyInst, unsigned Op) {
321
60
  assert((TargetRegisterInfo::isPhysicalRegister(
322
60
             CopyInst->getOperand(Op).getReg())) &&
323
60
         "Copies of non physical registers should not be considered here.\n");
324
60
325
60
  const MachineFunction &MF = *CopyInst->getMF();
326
60
  const MachineRegisterInfo &MRI = MF.getRegInfo();
327
60
  const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
328
60
  const RegisterBankInfo &RBI =
329
60
      *CopyInst->getMF()->getSubtarget().getRegBankInfo();
330
60
  const RegisterBank *Bank =
331
60
      RBI.getRegBank(CopyInst->getOperand(Op).getReg(), MRI, TRI);
332
60
333
60
  if (Bank == &Mips::FPRBRegBank)
334
24
    setTypes(MI, InstType::FloatingPoint);
335
36
  else if (Bank == &Mips::GPRBRegBank)
336
36
    setTypes(MI, InstType::Integer);
337
36
  else
338
36
    
llvm_unreachable0
("Unsupported register bank.\n");
339
60
}
340
341
MipsRegisterBankInfo::InstType
342
417
MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) {
343
417
  visit(MI, nullptr);
344
417
  return getRecordedTypeForInstr(MI);
345
417
}
346
347
void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction(
348
3.78k
    llvm::StringRef FunctionName) {
349
3.78k
  if (MFName != FunctionName) {
350
477
    MFName = FunctionName;
351
477
    WaitingQueues.clear();
352
477
    Types.clear();
353
477
  }
354
3.78k
}
355
356
const RegisterBankInfo::InstructionMapping &
357
3.78k
MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
358
3.78k
359
3.78k
  static TypeInfoForMF TI;
360
3.78k
361
3.78k
  // Reset TI internal data when MF changes.
362
3.78k
  TI.cleanupIfNewFunction(MI.getMF()->getName());
363
3.78k
364
3.78k
  unsigned Opc = MI.getOpcode();
365
3.78k
  const MachineFunction &MF = *MI.getParent()->getParent();
366
3.78k
  const MachineRegisterInfo &MRI = MF.getRegInfo();
367
3.78k
368
3.78k
  if (MI.getOpcode() != TargetOpcode::G_PHI) {
369
3.70k
    const RegisterBankInfo::InstructionMapping &Mapping =
370
3.70k
        getInstrMappingImpl(MI);
371
3.70k
    if (Mapping.isValid())
372
2.12k
      return Mapping;
373
1.65k
  }
374
1.65k
375
1.65k
  using namespace TargetOpcode;
376
1.65k
377
1.65k
  unsigned NumOperands = MI.getNumOperands();
378
1.65k
  const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
379
1.65k
  unsigned MappingID = DefaultMappingID;
380
1.65k
  const unsigned CustomMappingID = 1;
381
1.65k
382
1.65k
  switch (Opc) {
383
1.65k
  case G_TRUNC:
384
479
  case G_ADD:
385
479
  case G_SUB:
386
479
  case G_MUL:
387
479
  case G_UMULH:
388
479
  case G_ZEXTLOAD:
389
479
  case G_SEXTLOAD:
390
479
  case G_GEP:
391
479
  case G_AND:
392
479
  case G_OR:
393
479
  case G_XOR:
394
479
  case G_SHL:
395
479
  case G_ASHR:
396
479
  case G_LSHR:
397
479
  case G_SDIV:
398
479
  case G_UDIV:
399
479
  case G_SREM:
400
479
  case G_UREM:
401
479
    OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
402
479
    break;
403
479
  case G_LOAD: {
404
221
    unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
405
221
    InstType InstTy = InstType::Integer;
406
221
    if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) {
407
171
      InstTy = TI.determineInstType(&MI);
408
171
    }
409
221
410
221
    if (InstTy == InstType::FloatingPoint ||
411
221
        
(185
Size == 64185
&&
InstTy == InstType::Ambiguous57
)) { // fprb
412
76
      OperandsMapping =
413
76
          getOperandsMapping({Size == 32 ? 
&Mips::ValueMappings[Mips::SPRIdx]19
414
76
                                         : 
&Mips::ValueMappings[Mips::DPRIdx]57
,
415
76
                              &Mips::ValueMappings[Mips::GPRIdx]});
416
76
      break;
417
145
    } else { // gprb
418
145
      OperandsMapping =
419
145
          getOperandsMapping({Size <= 32 ? 
&Mips::ValueMappings[Mips::GPRIdx]128
420
145
                                         : 
&Mips::ValueMappings[Mips::DPRIdx]17
,
421
145
                              &Mips::ValueMappings[Mips::GPRIdx]});
422
145
      if (Size == 64)
423
17
        MappingID = CustomMappingID;
424
145
    }
425
221
426
221
    
break145
;
427
221
  }
428
221
  case G_STORE: {
429
101
    unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
430
101
    InstType InstTy = InstType::Integer;
431
101
    if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) {
432
101
      InstTy = TI.determineInstType(&MI);
433
101
    }
434
101
435
101
    if (InstTy == InstType::FloatingPoint ||
436
101
        
(79
Size == 6479
&&
InstTy == InstType::Ambiguous44
)) { // fprb
437
52
      OperandsMapping =
438
52
          getOperandsMapping({Size == 32 ? 
&Mips::ValueMappings[Mips::SPRIdx]8
439
52
                                         : 
&Mips::ValueMappings[Mips::DPRIdx]44
,
440
52
                              &Mips::ValueMappings[Mips::GPRIdx]});
441
52
      break;
442
52
    } else { // gprb
443
49
      OperandsMapping =
444
49
          getOperandsMapping({Size <= 32 ? 
&Mips::ValueMappings[Mips::GPRIdx]35
445
49
                                         : 
&Mips::ValueMappings[Mips::DPRIdx]14
,
446
49
                              &Mips::ValueMappings[Mips::GPRIdx]});
447
49
      if (Size == 64)
448
14
        MappingID = CustomMappingID;
449
49
    }
450
101
    
break49
;
451
101
  }
452
101
  case G_PHI: {
453
79
    unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
454
79
    InstType InstTy = InstType::Integer;
455
79
    if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) {
456
79
      InstTy = TI.determineInstType(&MI);
457
79
    }
458
79
459
79
    // PHI is copylike and should have one regbank in mapping for def register.
460
79
    if (InstTy == InstType::Integer && 
Size == 6423
) { // fprb
461
14
      OperandsMapping =
462
14
          getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx]});
463
14
      return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping,
464
14
                                   /*NumOperands=*/1);
465
14
    }
466
65
    // Use default handling for PHI, i.e. set reg bank of def operand to match
467
65
    // register banks of use operands.
468
65
    const RegisterBankInfo::InstructionMapping &Mapping =
469
65
        getInstrMappingImpl(MI);
470
65
    return Mapping;
471
65
  }
472
68
  case G_SELECT: {
473
68
    unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
474
68
    InstType InstTy = InstType::Integer;
475
68
    if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) {
476
66
      InstTy = TI.determineInstType(&MI);
477
66
    }
478
68
479
68
    if (InstTy == InstType::FloatingPoint ||
480
68
        
(51
Size == 6451
&&
InstTy == InstType::Ambiguous22
)) { // fprb
481
31
      const RegisterBankInfo::ValueMapping *Bank =
482
31
          Size == 32 ? 
&Mips::ValueMappings[Mips::SPRIdx]9
483
31
                     : 
&Mips::ValueMappings[Mips::DPRIdx]22
;
484
31
      OperandsMapping = getOperandsMapping(
485
31
          {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
486
31
      break;
487
37
    } else { // gprb
488
37
      const RegisterBankInfo::ValueMapping *Bank =
489
37
          Size <= 32 ? 
&Mips::ValueMappings[Mips::GPRIdx]29
490
37
                     : 
&Mips::ValueMappings[Mips::DPRIdx]8
;
491
37
      OperandsMapping = getOperandsMapping(
492
37
          {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
493
37
      if (Size == 64)
494
8
        MappingID = CustomMappingID;
495
37
    }
496
68
    
break37
;
497
68
  }
498
68
  case G_UNMERGE_VALUES: {
499
6
    OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx],
500
6
                                          &Mips::ValueMappings[Mips::GPRIdx],
501
6
                                          &Mips::ValueMappings[Mips::DPRIdx]});
502
6
    MappingID = CustomMappingID;
503
6
    break;
504
68
  }
505
68
  case G_MERGE_VALUES: {
506
13
    OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx],
507
13
                                          &Mips::ValueMappings[Mips::GPRIdx],
508
13
                                          &Mips::ValueMappings[Mips::GPRIdx]});
509
13
    MappingID = CustomMappingID;
510
13
    break;
511
68
  }
512
68
  case G_FADD:
513
53
  case G_FSUB:
514
53
  case G_FMUL:
515
53
  case G_FDIV:
516
53
  case G_FABS:
517
53
  case G_FSQRT:{
518
53
    unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
519
53
    assert((Size == 32 || Size == 64) && "Unsupported floating point size");
520
53
    OperandsMapping = Size == 32 ? 
&Mips::ValueMappings[Mips::SPRIdx]29
521
53
                                 : 
&Mips::ValueMappings[Mips::DPRIdx]24
;
522
53
    break;
523
53
  }
524
53
  case G_FCONSTANT: {
525
12
    unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
526
12
    assert((Size == 32 || Size == 64) && "Unsupported floating point size");
527
12
    const RegisterBankInfo::ValueMapping *FPRValueMapping =
528
12
        Size == 32 ? 
&Mips::ValueMappings[Mips::SPRIdx]5
529
12
                   : 
&Mips::ValueMappings[Mips::DPRIdx]7
;
530
12
    OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr});
531
12
    break;
532
53
  }
533
60
  case G_FCMP: {
534
60
    unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
535
60
    assert((Size == 32 || Size == 64) && "Unsupported floating point size");
536
60
    const RegisterBankInfo::ValueMapping *FPRValueMapping =
537
60
        Size == 32 ? 
&Mips::ValueMappings[Mips::SPRIdx]30
538
60
                   : 
&Mips::ValueMappings[Mips::DPRIdx]30
;
539
60
    OperandsMapping =
540
60
        getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
541
60
                            FPRValueMapping, FPRValueMapping});
542
60
    break;
543
53
  }
544
53
  case G_FPEXT:
545
4
    OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx],
546
4
                                          &Mips::ValueMappings[Mips::SPRIdx]});
547
4
    break;
548
53
  case G_FPTRUNC:
549
4
    OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::SPRIdx],
550
4
                                          &Mips::ValueMappings[Mips::DPRIdx]});
551
4
    break;
552
53
  case G_FPTOSI: {
553
16
    unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
554
16
    assert((MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() == 32) &&
555
16
           "Unsupported integer size");
556
16
    assert((SizeFP == 32 || SizeFP == 64) && "Unsupported floating point size");
557
16
    OperandsMapping = getOperandsMapping({
558
16
        &Mips::ValueMappings[Mips::GPRIdx],
559
16
        SizeFP == 32 ? 
&Mips::ValueMappings[Mips::SPRIdx]8
560
16
                     : 
&Mips::ValueMappings[Mips::DPRIdx]8
,
561
16
    });
562
16
    break;
563
53
  }
564
53
  case G_SITOFP: {
565
16
    unsigned SizeInt = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
566
16
    unsigned SizeFP = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
567
16
    (void)SizeInt;
568
16
    assert((SizeInt == 32) && "Unsupported integer size");
569
16
    assert((SizeFP == 32 || SizeFP == 64) && "Unsupported floating point size");
570
16
    OperandsMapping =
571
16
        getOperandsMapping({SizeFP == 32 ? 
&Mips::ValueMappings[Mips::SPRIdx]8
572
16
                                         : 
&Mips::ValueMappings[Mips::DPRIdx]8
,
573
16
                            &Mips::ValueMappings[Mips::GPRIdx]});
574
16
    break;
575
53
  }
576
462
  case G_CONSTANT:
577
462
  case G_FRAME_INDEX:
578
462
  case G_GLOBAL_VALUE:
579
462
  case G_BRCOND:
580
462
    OperandsMapping =
581
462
        getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr});
582
462
    break;
583
462
  case G_ICMP:
584
62
    OperandsMapping =
585
62
        getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
586
62
                            &Mips::ValueMappings[Mips::GPRIdx],
587
62
                            &Mips::ValueMappings[Mips::GPRIdx]});
588
62
    break;
589
462
  default:
590
0
    return getInvalidInstructionMapping();
591
1.57k
  }
592
1.57k
593
1.57k
  return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping,
594
1.57k
                               NumOperands);
595
1.57k
}
596
597
using InstListTy = GISelWorkList<4>;
598
namespace {
599
class InstManager : public GISelChangeObserver {
600
  InstListTy &InstList;
601
602
public:
603
72
  InstManager(InstListTy &Insts) : InstList(Insts) {}
604
605
268
  void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); }
606
0
  void erasingInstr(MachineInstr &MI) override {}
607
14
  void changingInstr(MachineInstr &MI) override {}
608
14
  void changedInstr(MachineInstr &MI) override {}
609
};
610
} // end anonymous namespace
611
612
/// Here we have to narrowScalar s64 operands to s32, combine away
613
/// G_MERGE/G_UNMERGE and erase instructions that became dead in the process.
614
/// We manually assign 32 bit gprb to register operands of all new instructions
615
/// that got created in the process since they will not end up in RegBankSelect
616
/// loop. Careful not to delete instruction after MI i.e. MI.getIterator()++.
617
void MipsRegisterBankInfo::applyMappingImpl(
618
72
    const OperandsMapper &OpdMapper) const {
619
72
  MachineInstr &MI = OpdMapper.getMI();
620
72
  InstListTy NewInstrs;
621
72
  MachineIRBuilder B(MI);
622
72
  MachineFunction *MF = MI.getMF();
623
72
  MachineRegisterInfo &MRI = OpdMapper.getMRI();
624
72
625
72
  InstManager NewInstrObserver(NewInstrs);
626
72
  GISelObserverWrapper WrapperObserver(&NewInstrObserver);
627
72
  LegalizerHelper Helper(*MF, WrapperObserver, B);
628
72
  LegalizationArtifactCombiner ArtCombiner(
629
72
      B, MF->getRegInfo(), *MF->getSubtarget().getLegalizerInfo());
630
72
631
72
  switch (MI.getOpcode()) {
632
72
  case TargetOpcode::G_LOAD:
633
53
  case TargetOpcode::G_STORE:
634
53
  case TargetOpcode::G_PHI:
635
53
  case TargetOpcode::G_SELECT: {
636
53
    Helper.narrowScalar(MI, 0, LLT::scalar(32));
637
53
    // Handle new instructions.
638
321
    while (!NewInstrs.empty()) {
639
268
      MachineInstr *NewMI = NewInstrs.pop_back_val();
640
268
      // This is new G_UNMERGE that was created during narrowScalar and will
641
268
      // not be considered for regbank selection. RegBankSelect for mips
642
268
      // visits/makes corresponding G_MERGE first. Combine them here.
643
268
      if (NewMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) {
644
61
        SmallVector<MachineInstr *, 2> DeadInstrs;
645
61
        ArtCombiner.tryCombineMerges(*NewMI, DeadInstrs);
646
61
        for (MachineInstr *DeadMI : DeadInstrs)
647
107
          DeadMI->eraseFromParent();
648
61
      }
649
207
      // This G_MERGE will be combined away when its corresponding G_UNMERGE
650
207
      // gets regBankSelected.
651
207
      else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
652
39
        continue;
653
168
      else
654
168
        // Manually set register banks for all register operands to 32 bit gprb.
655
495
        
for (auto Op : NewMI->operands())168
{
656
495
          if (Op.isReg()) {
657
402
            assert(MRI.getType(Op.getReg()).getSizeInBits() == 32 &&
658
402
                   "Only 32 bit gprb is handled here.\n");
659
402
            MRI.setRegBank(Op.getReg(), getRegBank(Mips::GPRBRegBankID));
660
402
          }
661
495
        }
662
268
    }
663
53
    return;
664
53
  }
665
53
  case TargetOpcode::G_UNMERGE_VALUES: {
666
6
    SmallVector<MachineInstr *, 2> DeadInstrs;
667
6
    ArtCombiner.tryCombineMerges(MI, DeadInstrs);
668
6
    for (MachineInstr *DeadMI : DeadInstrs)
669
12
      DeadMI->eraseFromParent();
670
6
    return;
671
53
  }
672
53
  default:
673
13
    break;
674
13
  }
675
13
676
13
  return applyDefaultMapping(OpdMapper);
677
13
}