Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/X86/X86RegisterBankInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- X86RegisterBankInfo.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 X86.
10
/// \todo This should be generated by TableGen.
11
//===----------------------------------------------------------------------===//
12
13
#include "X86RegisterBankInfo.h"
14
#include "X86InstrInfo.h"
15
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
16
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
17
#include "llvm/CodeGen/MachineRegisterInfo.h"
18
#include "llvm/CodeGen/TargetRegisterInfo.h"
19
20
#define GET_TARGET_REGBANK_IMPL
21
#include "X86GenRegisterBank.inc"
22
23
using namespace llvm;
24
// This file will be TableGen'ed at some point.
25
#define GET_TARGET_REGBANK_INFO_IMPL
26
#include "X86GenRegisterBankInfo.def"
27
28
X86RegisterBankInfo::X86RegisterBankInfo(const TargetRegisterInfo &TRI)
29
15.2k
    : X86GenRegisterBankInfo() {
30
15.2k
31
15.2k
  // validate RegBank initialization.
32
15.2k
  const RegisterBank &RBGPR = getRegBank(X86::GPRRegBankID);
33
15.2k
  (void)RBGPR;
34
15.2k
  assert(&X86::GPRRegBank == &RBGPR && "Incorrect RegBanks inizalization.");
35
15.2k
36
15.2k
  // The GPR register bank is fully defined by all the registers in
37
15.2k
  // GR64 + its subclasses.
38
15.2k
  assert(RBGPR.covers(*TRI.getRegClass(X86::GR64RegClassID)) &&
39
15.2k
         "Subclass not added?");
40
15.2k
  assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
41
15.2k
}
42
43
const RegisterBank &X86RegisterBankInfo::getRegBankFromRegClass(
44
10.5k
    const TargetRegisterClass &RC) const {
45
10.5k
46
10.5k
  if (X86::GR8RegClass.hasSubClassEq(&RC) ||
47
10.5k
      
X86::GR16RegClass.hasSubClassEq(&RC)9.68k
||
48
10.5k
      
X86::GR32RegClass.hasSubClassEq(&RC)9.20k
||
49
10.5k
      
X86::GR64RegClass.hasSubClassEq(&RC)6.25k
)
50
6.35k
    return getRegBank(X86::GPRRegBankID);
51
4.23k
52
4.23k
  if (X86::FR32XRegClass.hasSubClassEq(&RC) ||
53
4.23k
      
X86::FR64XRegClass.hasSubClassEq(&RC)1.17k
||
54
4.23k
      
X86::VR128XRegClass.hasSubClassEq(&RC)1.17k
||
55
4.23k
      
X86::VR256XRegClass.hasSubClassEq(&RC)1.17k
||
56
4.23k
      
X86::VR512RegClass.hasSubClassEq(&RC)337
)
57
4.23k
    return getRegBank(X86::VECRRegBankID);
58
0
59
0
  llvm_unreachable("Unsupported register kind yet.");
60
0
}
61
62
X86GenRegisterBankInfo::PartialMappingIdx
63
3.09k
X86GenRegisterBankInfo::getPartialMappingIdx(const LLT &Ty, bool isFP) {
64
3.09k
  if ((Ty.isScalar() && 
!isFP2.16k
) ||
Ty.isPointer()1.65k
) {
65
2.10k
    switch (Ty.getSizeInBits()) {
66
2.10k
    case 1:
67
416
    case 8:
68
416
      return PMI_GPR8;
69
416
    case 16:
70
146
      return PMI_GPR16;
71
985
    case 32:
72
985
      return PMI_GPR32;
73
551
    case 64:
74
551
      return PMI_GPR64;
75
416
    case 128:
76
3
      return PMI_VEC128;
77
416
      
break0
;
78
416
    default:
79
0
      llvm_unreachable("Unsupported register size.");
80
992
    }
81
992
  } else if (Ty.isScalar()) {
82
723
    switch (Ty.getSizeInBits()) {
83
723
    case 32:
84
245
      return PMI_FP32;
85
723
    case 64:
86
202
      return PMI_FP64;
87
723
    case 128:
88
276
      return PMI_VEC128;
89
723
    default:
90
0
      llvm_unreachable("Unsupported register size.");
91
269
    }
92
269
  } else {
93
269
    switch (Ty.getSizeInBits()) {
94
269
    case 128:
95
151
      return PMI_VEC128;
96
269
    case 256:
97
83
      return PMI_VEC256;
98
269
    case 512:
99
35
      return PMI_VEC512;
100
269
    default:
101
0
      llvm_unreachable("Unsupported register size.");
102
0
    }
103
0
  }
104
0
105
0
  return PMI_None;
106
0
}
107
108
void X86RegisterBankInfo::getInstrPartialMappingIdxs(
109
    const MachineInstr &MI, const MachineRegisterInfo &MRI, const bool isFP,
110
1.44k
    SmallVectorImpl<PartialMappingIdx> &OpRegBankIdx) {
111
1.44k
112
1.44k
  unsigned NumOperands = MI.getNumOperands();
113
4.47k
  for (unsigned Idx = 0; Idx < NumOperands; 
++Idx3.03k
) {
114
3.03k
    auto &MO = MI.getOperand(Idx);
115
3.03k
    if (!MO.isReg())
116
360
      OpRegBankIdx[Idx] = PMI_None;
117
2.67k
    else
118
2.67k
      OpRegBankIdx[Idx] = getPartialMappingIdx(MRI.getType(MO.getReg()), isFP);
119
3.03k
  }
120
1.44k
}
121
122
bool X86RegisterBankInfo::getInstrValueMapping(
123
    const MachineInstr &MI,
124
    const SmallVectorImpl<PartialMappingIdx> &OpRegBankIdx,
125
1.52k
    SmallVectorImpl<const ValueMapping *> &OpdsMapping) {
126
1.52k
127
1.52k
  unsigned NumOperands = MI.getNumOperands();
128
4.83k
  for (unsigned Idx = 0; Idx < NumOperands; 
++Idx3.30k
) {
129
3.30k
    if (!MI.getOperand(Idx).isReg())
130
416
      continue;
131
2.89k
132
2.89k
    auto Mapping = getValueMapping(OpRegBankIdx[Idx], 1);
133
2.89k
    if (!Mapping->isValid())
134
0
      return false;
135
2.89k
136
2.89k
    OpdsMapping[Idx] = Mapping;
137
2.89k
  }
138
1.52k
  return true;
139
1.52k
}
140
141
const RegisterBankInfo::InstructionMapping &
142
X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI,
143
252
                                            bool isFP) const {
144
252
  const MachineFunction &MF = *MI.getParent()->getParent();
145
252
  const MachineRegisterInfo &MRI = MF.getRegInfo();
146
252
147
252
  unsigned NumOperands = MI.getNumOperands();
148
252
  LLT Ty = MRI.getType(MI.getOperand(0).getReg());
149
252
150
252
  if (NumOperands != 3 || (Ty != MRI.getType(MI.getOperand(1).getReg())) ||
151
252
      (Ty != MRI.getType(MI.getOperand(2).getReg())))
152
252
    
llvm_unreachable0
("Unsupported operand mapping yet.");
153
252
154
252
  auto Mapping = getValueMapping(getPartialMappingIdx(Ty, isFP), 3);
155
252
  return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands);
156
252
}
157
158
const RegisterBankInfo::InstructionMapping &
159
3.33k
X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
160
3.33k
  const MachineFunction &MF = *MI.getParent()->getParent();
161
3.33k
  const MachineRegisterInfo &MRI = MF.getRegInfo();
162
3.33k
  unsigned Opc = MI.getOpcode();
163
3.33k
164
3.33k
  // Try the default logic for non-generic instructions that are either copies
165
3.33k
  // or already have some operands assigned to banks.
166
3.33k
  if (!isPreISelGenericOpcode(Opc) || 
Opc == TargetOpcode::G_PHI1.75k
) {
167
1.59k
    const InstructionMapping &Mapping = getInstrMappingImpl(MI);
168
1.59k
    if (Mapping.isValid())
169
1.54k
      return Mapping;
170
1.79k
  }
171
1.79k
172
1.79k
  switch (Opc) {
173
1.79k
  case TargetOpcode::G_ADD:
174
194
  case TargetOpcode::G_SUB:
175
194
  case TargetOpcode::G_MUL:
176
194
    return getSameOperandsMapping(MI, false);
177
194
  case TargetOpcode::G_FADD:
178
58
  case TargetOpcode::G_FSUB:
179
58
  case TargetOpcode::G_FMUL:
180
58
  case TargetOpcode::G_FDIV:
181
58
    return getSameOperandsMapping(MI, true);
182
60
  case TargetOpcode::G_SHL:
183
60
  case TargetOpcode::G_LSHR:
184
60
  case TargetOpcode::G_ASHR: {
185
60
    unsigned NumOperands = MI.getNumOperands();
186
60
    LLT Ty = MRI.getType(MI.getOperand(0).getReg());
187
60
188
60
    auto Mapping = getValueMapping(getPartialMappingIdx(Ty, false), 3);
189
60
    return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands);
190
60
191
60
  }
192
1.48k
  default:
193
1.48k
    break;
194
1.48k
  }
195
1.48k
196
1.48k
  unsigned NumOperands = MI.getNumOperands();
197
1.48k
  SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
198
1.48k
199
1.48k
  switch (Opc) {
200
1.48k
  case TargetOpcode::G_FPEXT:
201
14
  case TargetOpcode::G_FPTRUNC:
202
14
  case TargetOpcode::G_FCONSTANT:
203
14
    // Instruction having only floating-point operands (all scalars in VECRReg)
204
14
    getInstrPartialMappingIdxs(MI, MRI, /* isFP */ true, OpRegBankIdx);
205
14
    break;
206
24
  case TargetOpcode::G_SITOFP:
207
24
  case TargetOpcode::G_FPTOSI: {
208
24
    // Some of the floating-point instructions have mixed GPR and FP operands:
209
24
    // fine-tune the computed mapping.
210
24
    auto &Op0 = MI.getOperand(0);
211
24
    auto &Op1 = MI.getOperand(1);
212
24
    const LLT Ty0 = MRI.getType(Op0.getReg());
213
24
    const LLT Ty1 = MRI.getType(Op1.getReg());
214
24
215
24
    bool FirstArgIsFP = Opc == TargetOpcode::G_SITOFP;
216
24
    bool SecondArgIsFP = Opc == TargetOpcode::G_FPTOSI;
217
24
    OpRegBankIdx[0] = getPartialMappingIdx(Ty0, /* isFP */ FirstArgIsFP);
218
24
    OpRegBankIdx[1] = getPartialMappingIdx(Ty1, /* isFP */ SecondArgIsFP);
219
24
    break;
220
24
  }
221
56
  case TargetOpcode::G_FCMP: {
222
56
    LLT Ty1 = MRI.getType(MI.getOperand(2).getReg());
223
56
    LLT Ty2 = MRI.getType(MI.getOperand(3).getReg());
224
56
    (void)Ty2;
225
56
    assert(Ty1.getSizeInBits() == Ty2.getSizeInBits() &&
226
56
           "Mismatched operand sizes for G_FCMP");
227
56
228
56
    unsigned Size = Ty1.getSizeInBits();
229
56
    (void)Size;
230
56
    assert((Size == 32 || Size == 64) && "Unsupported size for G_FCMP");
231
56
232
56
    auto FpRegBank = getPartialMappingIdx(Ty1, /* isFP */ true);
233
56
    OpRegBankIdx = {PMI_GPR8,
234
56
                    /* Predicate */ PMI_None, FpRegBank, FpRegBank};
235
56
    break;
236
24
  }
237
452
  case TargetOpcode::G_TRUNC:
238
452
  case TargetOpcode::G_ANYEXT: {
239
452
    auto &Op0 = MI.getOperand(0);
240
452
    auto &Op1 = MI.getOperand(1);
241
452
    const LLT Ty0 = MRI.getType(Op0.getReg());
242
452
    const LLT Ty1 = MRI.getType(Op1.getReg());
243
452
244
452
    bool isFPTrunc = (Ty0.getSizeInBits() == 32 || 
Ty0.getSizeInBits() == 64328
) &&
245
452
                     
Ty1.getSizeInBits() == 128229
&&
Opc == TargetOpcode::G_TRUNC215
;
246
452
    bool isFPAnyExt =
247
452
        Ty0.getSizeInBits() == 128 &&
248
452
        
(61
Ty1.getSizeInBits() == 3261
||
Ty1.getSizeInBits() == 6427
) &&
249
452
        
Opc == TargetOpcode::G_ANYEXT61
;
250
452
251
452
    getInstrPartialMappingIdxs(MI, MRI, /* isFP */ isFPTrunc || 
isFPAnyExt237
,
252
452
                               OpRegBankIdx);
253
452
  } break;
254
936
  default:
255
936
    // Track the bank of each register, use NotFP mapping (all scalars in GPRs)
256
936
    getInstrPartialMappingIdxs(MI, MRI, /* isFP */ false, OpRegBankIdx);
257
936
    break;
258
1.48k
  }
259
1.48k
260
1.48k
  // Finally construct the computed mapping.
261
1.48k
  SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
262
1.48k
  if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
263
0
    return getInvalidInstructionMapping();
264
1.48k
265
1.48k
  return getInstructionMapping(DefaultMappingID, /* Cost */ 1,
266
1.48k
                               getOperandsMapping(OpdsMapping), NumOperands);
267
1.48k
}
268
269
void X86RegisterBankInfo::applyMappingImpl(
270
4
    const OperandsMapper &OpdMapper) const {
271
4
  return applyDefaultMapping(OpdMapper);
272
4
}
273
274
RegisterBankInfo::InstructionMappings
275
631
X86RegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const {
276
631
277
631
  const MachineFunction &MF = *MI.getParent()->getParent();
278
631
  const TargetSubtargetInfo &STI = MF.getSubtarget();
279
631
  const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
280
631
  const MachineRegisterInfo &MRI = MF.getRegInfo();
281
631
282
631
  switch (MI.getOpcode()) {
283
631
  case TargetOpcode::G_LOAD:
284
74
  case TargetOpcode::G_STORE:
285
74
  case TargetOpcode::G_IMPLICIT_DEF: {
286
74
    // we going to try to map 32/64 bit to PMI_FP32/PMI_FP64
287
74
    unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
288
74
    if (Size != 32 && 
Size != 6445
)
289
35
      break;
290
39
291
39
    unsigned NumOperands = MI.getNumOperands();
292
39
293
39
    // Track the bank of each register, use FP mapping (all scalars in VEC)
294
39
    SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
295
39
    getInstrPartialMappingIdxs(MI, MRI, /* isFP */ true, OpRegBankIdx);
296
39
297
39
    // Finally construct the computed mapping.
298
39
    SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
299
39
    if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
300
0
      break;
301
39
302
39
    const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping(
303
39
        /*ID*/ 1, /*Cost*/ 1, getOperandsMapping(OpdsMapping), NumOperands);
304
39
    InstructionMappings AltMappings;
305
39
    AltMappings.push_back(&Mapping);
306
39
    return AltMappings;
307
39
  }
308
557
  default:
309
557
    break;
310
592
  }
311
592
  return RegisterBankInfo::getInstrAlternativeMappings(MI);
312
592
}