LLVM: lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
21
22#define GET_TARGET_REGBANK_IMPL
23#include "RISCVGenRegisterBank.inc"
24
25namespace llvm {
27
29
30 {0, 32, GPRBRegBank},
31 {0, 64, GPRBRegBank},
32 {0, 16, FPRBRegBank},
33 {0, 32, FPRBRegBank},
34 {0, 64, FPRBRegBank},
35 {0, 64, VRBRegBank},
36 {0, 128, VRBRegBank},
37 {0, 256, VRBRegBank},
38 {0, 512, VRBRegBank},
39
40};
41
53
55
56 {nullptr, 0},
57
61
65
69
73
77
81
85
89
93};
94
107}
108}
109
110using namespace llvm;
111
114
116 unsigned Idx;
117 switch (Size) {
118 default:
120 case 16:
122 break;
123 case 32:
125 break;
126 case 64:
128 break;
129 }
131}
132
133
134bool RISCVRegisterBankInfo::hasFPConstraints(
138 return true;
139
140
141
142 if (MI.getOpcode() != TargetOpcode::COPY)
143 return false;
144
145 return getRegBank(MI.getOperand(0).getReg(), MRI, TRI) == &RISCV::FPRBRegBank;
146}
147
148bool RISCVRegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
151 switch (MI.getOpcode()) {
152 case RISCV::G_FCVT_W_RV64:
153 case RISCV::G_FCVT_WU_RV64:
154 case RISCV::G_FCLASS:
155 case TargetOpcode::G_FPTOSI:
156 case TargetOpcode::G_FPTOUI:
157 case TargetOpcode::G_FCMP:
158 return true;
159 default:
160 break;
161 }
162
163 return hasFPConstraints(MI, MRI, TRI);
164}
165
166bool RISCVRegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,
169 switch (MI.getOpcode()) {
170 case TargetOpcode::G_SITOFP:
171 case TargetOpcode::G_UITOFP:
172 return true;
173 default:
174 break;
175 }
176
177 return hasFPConstraints(MI, MRI, TRI);
178}
179
180bool RISCVRegisterBankInfo::anyUseOnlyUseFP(
184 MRI.use_nodbg_instructions(Def),
185 [&](const MachineInstr &UseMI) { return onlyUsesFP(UseMI, MRI, TRI); });
186}
187
189 unsigned Idx;
190
191 if (Size <= 64)
193 else if (Size == 128)
195 else if (Size == 256)
197 else if (Size == 512)
199 else
201
203}
204
207 const unsigned Opc = MI.getOpcode();
208
209
210
214 return Mapping;
215 }
216
221
222 unsigned GPRSize = getMaximumSize(RISCV::GPRBRegBankID);
223 assert((GPRSize == 32 || GPRSize == 64) && "Unexpected GPR size");
224
225 unsigned NumOperands = MI.getNumOperands();
229
230 switch (Opc) {
231 case TargetOpcode::G_ADD:
232 case TargetOpcode::G_SUB:
233 case TargetOpcode::G_SHL:
234 case TargetOpcode::G_ASHR:
235 case TargetOpcode::G_LSHR:
236 case TargetOpcode::G_AND:
237 case TargetOpcode::G_OR:
238 case TargetOpcode::G_XOR:
239 case TargetOpcode::G_MUL:
240 case TargetOpcode::G_SDIV:
241 case TargetOpcode::G_SREM:
242 case TargetOpcode::G_SMULH:
243 case TargetOpcode::G_SMAX:
244 case TargetOpcode::G_SMIN:
245 case TargetOpcode::G_UDIV:
246 case TargetOpcode::G_UREM:
247 case TargetOpcode::G_UMULH:
248 case TargetOpcode::G_UMAX:
249 case TargetOpcode::G_UMIN:
250 case TargetOpcode::G_PTR_ADD:
251 case TargetOpcode::G_PTRTOINT:
252 case TargetOpcode::G_INTTOPTR:
253 case TargetOpcode::G_FADD:
254 case TargetOpcode::G_FSUB:
255 case TargetOpcode::G_FMUL:
256 case TargetOpcode::G_FDIV:
257 case TargetOpcode::G_FABS:
258 case TargetOpcode::G_FNEG:
259 case TargetOpcode::G_FSQRT:
260 case TargetOpcode::G_FMAXNUM:
261 case TargetOpcode::G_FMINNUM: {
262 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
264
266 if (Ty.isVector())
270 else
271 Mapping = GPRValueMapping;
272
273#ifndef NDEBUG
274
275 for (unsigned Idx = 1; Idx != NumOperands; ++Idx) {
276 LLT OpTy = MRI.getType(MI.getOperand(Idx).getReg());
278 "Operand has incompatible type");
279
282 }
283#endif
284
286 }
287 case TargetOpcode::G_SEXTLOAD:
288 case TargetOpcode::G_ZEXTLOAD:
290 NumOperands);
291 case TargetOpcode::G_IMPLICIT_DEF: {
292 Register Dst = MI.getOperand(0).getReg();
293 LLT DstTy = MRI.getType(Dst);
295 auto Mapping = GPRValueMapping;
296
297
298
299
300
303 else if (anyUseOnlyUseFP(Dst, MRI, TRI))
305
307 NumOperands);
308 }
309 }
310
312
313 switch (Opc) {
314 case TargetOpcode::G_LOAD: {
315 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
317
318 OpdsMapping[1] = GPRValueMapping;
319
320 if (Ty.isVector()) {
322 break;
323 }
324
325 OpdsMapping[0] = GPRValueMapping;
326
327
329 break;
330
331
332 if (GPRSize == 32 && Size.getFixedValue() == 64) {
335 break;
336 }
337
338
339
340
341 if (anyUseOnlyUseFP(MI.getOperand(0).getReg(), MRI, TRI)) {
342
343
344
345
347 break;
348 }
349
350 break;
351 }
352 case TargetOpcode::G_STORE: {
353 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
355
356 OpdsMapping[1] = GPRValueMapping;
357
358 if (Ty.isVector()) {
360 break;
361 }
362
363 OpdsMapping[0] = GPRValueMapping;
364
365
367 break;
368
369
370 if (GPRSize == 32 && Size.getFixedValue() == 64) {
373 break;
374 }
375
379 break;
380 }
381 case TargetOpcode::G_SELECT: {
382 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
383
384 if (Ty.isVector()) {
386 LLT TestTy = MRI.getType(Sel.getCondReg());
387 assert(TestTy.isVector() && "Unexpected condition argument type");
388 OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] =
390 OpdsMapping[1] =
392 break;
393 }
394
395
396
397
398 unsigned NumFP = 0;
399
400
401 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
402 NumFP = 3;
403 } else {
404
405
406
407
408
409
410 if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
412 return onlyUsesFP(UseMI, MRI, TRI);
413 }))
414 ++NumFP;
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429 for (unsigned Idx = 2; Idx < 4; ++Idx) {
430 Register VReg = MI.getOperand(Idx).getReg();
434 ++NumFP;
435 }
436 }
437
438
439 OpdsMapping[1] = GPRValueMapping;
440
441 const ValueMapping *Mapping = GPRValueMapping;
442 if (NumFP >= 2)
444
445 OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] = Mapping;
446 break;
447 }
448 case RISCV::G_FCVT_W_RV64:
449 case RISCV::G_FCVT_WU_RV64:
450 case TargetOpcode::G_FPTOSI:
451 case TargetOpcode::G_FPTOUI:
452 case RISCV::G_FCLASS: {
453 LLT Ty = MRI.getType(MI.getOperand(1).getReg());
454 OpdsMapping[0] = GPRValueMapping;
456 break;
457 }
458 case TargetOpcode::G_SITOFP:
459 case TargetOpcode::G_UITOFP: {
460 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
462 OpdsMapping[1] = GPRValueMapping;
463 break;
464 }
465 case TargetOpcode::G_FCMP: {
466 LLT Ty = MRI.getType(MI.getOperand(2).getReg());
467
468 unsigned Size = Ty.getSizeInBits();
469
470 OpdsMapping[0] = GPRValueMapping;
472 break;
473 }
474 case TargetOpcode::G_MERGE_VALUES: {
475
476 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
477 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
480 OpdsMapping[1] = GPRValueMapping;
481 OpdsMapping[2] = GPRValueMapping;
482 }
483 break;
484 }
485 case TargetOpcode::G_UNMERGE_VALUES: {
486
487 LLT Ty = MRI.getType(MI.getOperand(2).getReg());
488 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
490 OpdsMapping[0] = GPRValueMapping;
491 OpdsMapping[1] = GPRValueMapping;
493 }
494 break;
495 }
496 case TargetOpcode::G_SPLAT_VECTOR: {
498 .getSizeInBits()
499 .getKnownMinValue());
500
501 LLT ScalarTy = MRI.getType(MI.getOperand(1).getReg());
503 if ((GPRSize == 32 && ScalarTy.getSizeInBits() == 64) ||
507 } else
508 OpdsMapping[1] = GPRValueMapping;
509 break;
510 }
511 case TargetOpcode::G_INTRINSIC: {
513
515 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntrinsicID)) {
516 unsigned ScalarIdx = -1;
517 if (II->hasScalarOperand()) {
518 ScalarIdx = II->ScalarOperand + 2;
519 }
520 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
523 continue;
525 if (Ty.isVector()) {
526 OpdsMapping[Idx] =
528 } else if (II->IsFPIntrinsic && ScalarIdx == Idx) {
529
531 } else {
532 OpdsMapping[Idx] = GPRValueMapping;
533 }
534 }
535 }
536 break;
537 }
538 default:
539
540 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
541 auto &MO = MI.getOperand(Idx);
542 if (!MO.isReg() || !MO.getReg())
543 continue;
544 LLT Ty = MRI.getType(MO.getReg());
545 if (!Ty.isValid())
546 continue;
547
548 if (Ty.isVector())
549 OpdsMapping[Idx] =
553 else
554 OpdsMapping[Idx] = GPRValueMapping;
555 }
556 break;
557 }
558
561}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
Register const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
static const RegisterBankInfo::ValueMapping * getFPValueMapping(unsigned Size)
Definition RISCVRegisterBankInfo.cpp:115
static const RegisterBankInfo::ValueMapping * getVRBValueMapping(unsigned Size)
Definition RISCVRegisterBankInfo.cpp:188
This file declares the targeting of the RegisterBankInfo class for RISC-V.
constexpr bool isVector() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
RISCVRegisterBankInfo(unsigned HwMode)
Definition RISCVRegisterBankInfo.cpp:112
const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override
Get the mapping of the different operands of MI on the register bank.
Definition RISCVRegisterBankInfo.cpp:206
Helper class that represents how the value of an instruction may be mapped and what is the related co...
bool isValid() const
Check whether this object is valid.
const InstructionMapping & getInstructionMapping(unsigned ID, unsigned Cost, const ValueMapping *OperandsMapping, unsigned NumOperands) const
Method to get a uniquely generated InstructionMapping.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
unsigned getMaximumSize(unsigned RegBankID) const
Get the maximum size in bits that fits in the given register bank.
const ValueMapping * getOperandsMapping(Iterator Begin, Iterator End) const
Get the uniquely generated array of ValueMapping for the elements of between Begin and End.
static const unsigned DefaultMappingID
Identifier used when the related instruction mapping instance is generated by target independent code...
unsigned HwMode
Current HwMode for the target.
const InstructionMapping & getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
Wrapper class representing virtual and physical registers.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const RegisterBankInfo::PartialMapping PartMappings[]
Definition RISCVRegisterBankInfo.cpp:28
ValueMappingIdx
Definition RISCVRegisterBankInfo.cpp:95
@ FPRB32Idx
Definition RISCVRegisterBankInfo.cpp:100
@ GPRB64Idx
Definition RISCVRegisterBankInfo.cpp:98
@ VRB128Idx
Definition RISCVRegisterBankInfo.cpp:103
@ InvalidIdx
Definition RISCVRegisterBankInfo.cpp:96
@ GPRB32Idx
Definition RISCVRegisterBankInfo.cpp:97
@ FPRB16Idx
Definition RISCVRegisterBankInfo.cpp:99
@ VRB512Idx
Definition RISCVRegisterBankInfo.cpp:105
@ FPRB64Idx
Definition RISCVRegisterBankInfo.cpp:101
@ VRB256Idx
Definition RISCVRegisterBankInfo.cpp:104
@ VRB64Idx
Definition RISCVRegisterBankInfo.cpp:102
const RegisterBankInfo::ValueMapping ValueMappings[]
Definition RISCVRegisterBankInfo.cpp:54
PartialMappingIdx
Definition RISCVRegisterBankInfo.cpp:42
@ PMI_VRB128
Definition RISCVRegisterBankInfo.cpp:49
@ PMI_VRB256
Definition RISCVRegisterBankInfo.cpp:50
@ PMI_GPRB32
Definition RISCVRegisterBankInfo.cpp:43
@ PMI_FPRB32
Definition RISCVRegisterBankInfo.cpp:46
@ PMI_FPRB64
Definition RISCVRegisterBankInfo.cpp:47
@ PMI_VRB64
Definition RISCVRegisterBankInfo.cpp:48
@ PMI_VRB512
Definition RISCVRegisterBankInfo.cpp:51
@ PMI_FPRB16
Definition RISCVRegisterBankInfo.cpp:45
@ PMI_GPRB64
Definition RISCVRegisterBankInfo.cpp:44
This is an optimization pass for GlobalISel generic memory operations.
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
LLVM_ABI bool isPreISelGenericFloatingPointOpcode(unsigned Opc)
Returns whether opcode Opc is a pre-isel generic floating-point opcode, having only floating-point op...
Helper struct that represents how a value is partially mapped into a register.
Helper struct that represents how a value is mapped through different register banks.