LLVM 24.0.0git
RISCVRegisterBankInfo.cpp
Go to the documentation of this file.
1//===-- RISCVRegisterBankInfo.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 RISC-V.
10/// \todo This should be generated by TableGen.
11//===----------------------------------------------------------------------===//
12
15#include "RISCVSubtarget.h"
21#include "llvm/IR/IntrinsicsRISCV.h"
22
23#define GET_TARGET_REGBANK_IMPL
24#include "RISCVGenRegisterBank.inc"
25
26namespace llvm {
27namespace RISCV {
28
30 // clang-format off
31 {0, 32, GPRBRegBank},
32 {0, 64, GPRBRegBank},
33 {0, 16, FPRBRegBank},
34 {0, 32, FPRBRegBank},
35 {0, 64, FPRBRegBank},
36 {0, 64, VRBRegBank},
37 {0, 128, VRBRegBank},
38 {0, 256, VRBRegBank},
39 {0, 512, VRBRegBank},
40 // clang-format on
41};
42
54
56 // Invalid value mapping.
57 {nullptr, 0},
58 // Maximum 3 GPR operands; 32 bit.
62 // Maximum 3 GPR operands; 64 bit.
66 // Maximum 3 FPR operands; 16 bit.
70 // Maximum 3 FPR operands; 32 bit.
74 // Maximum 3 FPR operands; 64 bit.
78 // Maximum 3 VR LMUL={1, MF2, MF4, MF8} operands.
82 // Maximum 3 VR LMUL=2 operands.
86 // Maximum 3 VR LMUL=4 operands.
90 // Maximum 3 VR LMUL=8 operands.
94};
95
108} // namespace RISCV
109} // namespace llvm
110
111using namespace llvm;
112
115
116const RegisterBank &
118 LLT Ty) const {
119 switch (RC.getID()) {
120 // Vector control and status register class
121 case RISCV::VCSRRegClassID:
122 return getRegBank(RISCV::GPRBRegBankID);
123 default:
124 // For all GPR register classes and others, use the default implementation
126 }
127}
128
130 unsigned Idx;
131 switch (Size) {
132 default:
133 llvm_unreachable("Unexpected size");
134 case 16:
135 Idx = RISCV::FPRB16Idx;
136 break;
137 case 32:
138 Idx = RISCV::FPRB32Idx;
139 break;
140 case 64:
141 Idx = RISCV::FPRB64Idx;
142 break;
143 }
144 return &RISCV::ValueMappings[Idx];
145}
146
147// TODO: Make this more like AArch64?
148bool RISCVRegisterBankInfo::hasFPConstraints(
149 const MachineInstr &MI, const MachineRegisterInfo &MRI,
150 const TargetRegisterInfo &TRI) const {
152 return true;
153
154 // If we have a copy instruction, we could be feeding floating point
155 // instructions.
156 if (MI.getOpcode() != TargetOpcode::COPY)
157 return false;
158
159 return getRegBank(MI.getOperand(0).getReg(), MRI, TRI) == &RISCV::FPRBRegBank;
160}
161
162bool RISCVRegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
164 const TargetRegisterInfo &TRI) const {
165 switch (MI.getOpcode()) {
166 case RISCV::G_FCVT_W_RV64:
167 case RISCV::G_FCVT_WU_RV64:
168 case RISCV::G_FCVT_X:
169 case RISCV::G_FCVT_XU:
170 case RISCV::G_FCLASS:
171 case TargetOpcode::G_FPTOSI:
172 case TargetOpcode::G_FPTOUI:
173 case TargetOpcode::G_LROUND:
174 case TargetOpcode::G_LLROUND:
175 case TargetOpcode::G_INTRINSIC_LRINT:
176 case TargetOpcode::G_INTRINSIC_LLRINT:
177 case TargetOpcode::G_FCMP:
178 return true;
179 default:
180 break;
181 }
182
183 return hasFPConstraints(MI, MRI, TRI);
184}
185
186bool RISCVRegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,
188 const TargetRegisterInfo &TRI) const {
189 switch (MI.getOpcode()) {
190 case TargetOpcode::G_SITOFP:
191 case TargetOpcode::G_UITOFP:
192 return true;
193 default:
194 break;
195 }
196
197 return hasFPConstraints(MI, MRI, TRI);
198}
199
200bool RISCVRegisterBankInfo::anyUseOnlyUseFP(
201 Register Def, const MachineRegisterInfo &MRI,
202 const TargetRegisterInfo &TRI) const {
203 return any_of(
205 [&](const MachineInstr &UseMI) { return onlyUsesFP(UseMI, MRI, TRI); });
206}
207
208/// Decide whether an s64 value on RV32 belongs in a GPRPair (an i64, needs
209/// Zilsd) rather than in FPR64 (an f64, needs D).
210///
211/// With extended LLTs the type answers this directly. Without them every
212/// 64-bit scalar is an ANY_SCALAR LLT, so i64 and f64 are indistinguishable --
213/// guessing from the uses gets it wrong, e.g. an f64 whose only use is a
214/// G_SELECT looks like an integer because G_SELECT is not itself floating
215/// point constrained. So fall back to using a GPRPair only where the value
216/// cannot be an f64 at all.
217static bool useGPRPairForS64(const RISCVSubtarget &ST, LLT Ty) {
218 if (!ST.hasStdExtZilsd())
219 return false;
221 return Ty.isInteger();
222 return !ST.hasStdExtD();
223}
224
226 unsigned Idx;
227
228 if (Size <= 64)
229 Idx = RISCV::VRB64Idx;
230 else if (Size == 128)
231 Idx = RISCV::VRB128Idx;
232 else if (Size == 256)
233 Idx = RISCV::VRB256Idx;
234 else if (Size == 512)
235 Idx = RISCV::VRB512Idx;
236 else
237 llvm::report_fatal_error("Invalid Size");
238
239 return &RISCV::ValueMappings[Idx];
240}
241
244 const unsigned Opc = MI.getOpcode();
245
246 // Try the default logic for non-generic instructions that are either copies
247 // or already have some operands assigned to banks.
248 if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {
249 const InstructionMapping &Mapping = getInstrMappingImpl(MI);
250 if (Mapping.isValid())
251 return Mapping;
252 }
253
254 const MachineFunction &MF = *MI.getParent()->getParent();
255 const MachineRegisterInfo &MRI = MF.getRegInfo();
256 const RISCVSubtarget &Subtarget = MF.getSubtarget<RISCVSubtarget>();
257 const TargetRegisterInfo &TRI = *Subtarget.getRegisterInfo();
258
259 unsigned GPRSize = Subtarget.getXLen();
260
261 unsigned NumOperands = MI.getNumOperands();
262 const ValueMapping *GPRValueMapping =
265
266 switch (Opc) {
267 case TargetOpcode::G_ADD:
268 case TargetOpcode::G_SUB:
269 case TargetOpcode::G_SHL:
270 case TargetOpcode::G_ASHR:
271 case TargetOpcode::G_LSHR:
272 case TargetOpcode::G_AND:
273 case TargetOpcode::G_OR:
274 case TargetOpcode::G_XOR:
275 case TargetOpcode::G_MUL:
276 case TargetOpcode::G_SDIV:
277 case TargetOpcode::G_SREM:
278 case TargetOpcode::G_SMULH:
279 case TargetOpcode::G_SMAX:
280 case TargetOpcode::G_SMIN:
281 case TargetOpcode::G_UDIV:
282 case TargetOpcode::G_UREM:
283 case TargetOpcode::G_UMULH:
284 case TargetOpcode::G_UMAX:
285 case TargetOpcode::G_UMIN:
286 case TargetOpcode::G_PTR_ADD:
287 case TargetOpcode::G_PTRTOINT:
288 case TargetOpcode::G_INTTOPTR:
289 case TargetOpcode::G_FADD:
290 case TargetOpcode::G_FSUB:
291 case TargetOpcode::G_FMUL:
292 case TargetOpcode::G_FDIV:
293 case TargetOpcode::G_FABS:
294 case TargetOpcode::G_FNEG:
295 case TargetOpcode::G_FSQRT:
296 case TargetOpcode::G_FMAXNUM:
297 case TargetOpcode::G_FMINNUM: {
298 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
299 TypeSize Size = Ty.getSizeInBits();
300
301 const ValueMapping *Mapping;
302 if (Ty.isVector())
303 Mapping = getVRBValueMapping(Size.getKnownMinValue());
305 Mapping = getFPValueMapping(Size.getFixedValue());
306 else
307 Mapping = GPRValueMapping;
308
309#ifndef NDEBUG
310 // Make sure all the operands are using similar size and type.
311 for (unsigned Idx = 1; Idx != NumOperands; ++Idx) {
312 LLT OpTy = MRI.getType(MI.getOperand(Idx).getReg());
313 assert(Ty.isVector() == OpTy.isVector() &&
314 "Operand has incompatible type");
315 // Don't check size for GPR.
317 assert(Size == OpTy.getSizeInBits() && "Operand has incompatible size");
318 }
319#endif // End NDEBUG
320
321 return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands);
322 }
323 case TargetOpcode::G_SEXTLOAD:
324 case TargetOpcode::G_ZEXTLOAD:
325 return getInstructionMapping(DefaultMappingID, /*Cost=*/1, GPRValueMapping,
326 NumOperands);
327 case TargetOpcode::G_IMPLICIT_DEF: {
328 Register Dst = MI.getOperand(0).getReg();
329 LLT DstTy = MRI.getType(Dst);
330 unsigned DstMinSize = DstTy.getSizeInBits().getKnownMinValue();
331 auto Mapping = GPRValueMapping;
332 // FIXME: May need to do a better job determining when to use FPRB.
333 // For example, the look through COPY case:
334 // %0:_(s32) = G_IMPLICIT_DEF
335 // %1:_(s32) = COPY %0
336 // $f10_d = COPY %1(s32)
337 if (DstTy.isVector())
338 Mapping = getVRBValueMapping(DstMinSize);
339 else if (anyUseOnlyUseFP(Dst, MRI, TRI))
340 Mapping = getFPValueMapping(DstMinSize);
341
342 return getInstructionMapping(DefaultMappingID, /*Cost=*/1, Mapping,
343 NumOperands);
344 }
345 }
346
347 SmallVector<const ValueMapping *, 4> OpdsMapping(NumOperands);
348
349 switch (Opc) {
350 case TargetOpcode::G_LOAD: {
351 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
352 TypeSize Size = Ty.getSizeInBits();
353
354 OpdsMapping[1] = GPRValueMapping;
355
356 if (Ty.isVector()) {
357 OpdsMapping[0] = getVRBValueMapping(Size.getKnownMinValue());
358 break;
359 }
360
361 OpdsMapping[0] = GPRValueMapping;
362
363 // Atomics always use GPR destinations. Don't refine any further.
364 if (cast<GLoad>(MI).isAtomic())
365 break;
366
367 // RV32 s64 loads: f64 (D) uses FPR64; i64 (Zilsd without D) uses a
368 // GPRPair.
369 if (GPRSize == 32 && Size.getFixedValue() == 64) {
371 if (useGPRPairForS64(ST, Ty)) {
372 OpdsMapping[0] = &RISCV::ValueMappings[RISCV::GPRB64Idx];
373 break;
374 }
375 assert(ST.hasStdExtD() && "s64 load without D or Zilsd");
376 OpdsMapping[0] = getFPValueMapping(Size);
377 break;
378 }
379
380 // Check if that load feeds fp instructions.
381 // In that case, we want the default mapping to be on FPR
382 // instead of blind map every scalar to GPR.
383 if (anyUseOnlyUseFP(MI.getOperand(0).getReg(), MRI, TRI)) {
384 // If we have at least one direct use in a FP instruction,
385 // assume this was a floating point load in the IR. If it was
386 // not, we would have had a bitcast before reaching that
387 // instruction.
388 OpdsMapping[0] = getFPValueMapping(Size);
389 break;
390 }
391
392 break;
393 }
394 case TargetOpcode::G_STORE: {
395 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
396 TypeSize Size = Ty.getSizeInBits();
397
398 OpdsMapping[1] = GPRValueMapping;
399
400 if (Ty.isVector()) {
401 OpdsMapping[0] = getVRBValueMapping(Size.getKnownMinValue());
402 break;
403 }
404
405 OpdsMapping[0] = GPRValueMapping;
406
407 // Atomics always use GPR sources. Don't refine any further.
408 if (cast<GStore>(MI).isAtomic())
409 break;
410
411 // RV32 s64 stores: f64 (D) uses FPR64; i64 (Zilsd without D) uses a
412 // GPRPair.
413 if (GPRSize == 32 && Size.getFixedValue() == 64) {
415 if (useGPRPairForS64(ST, Ty)) {
416 OpdsMapping[0] = &RISCV::ValueMappings[RISCV::GPRB64Idx];
417 break;
418 }
419 assert(ST.hasStdExtD() && "s64 store without D or Zilsd");
420 OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits());
421 break;
422 }
423
424 MachineInstr *DefMI = MRI.getVRegDef(MI.getOperand(0).getReg());
425 if (onlyDefinesFP(*DefMI, MRI, TRI))
426 OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits());
427 break;
428 }
429 case TargetOpcode::G_SELECT: {
430 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
431
432 if (Ty.isVector()) {
433 auto &Sel = cast<GSelect>(MI);
434 LLT TestTy = MRI.getType(Sel.getCondReg());
435 assert(TestTy.isVector() && "Unexpected condition argument type");
436 OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] =
437 getVRBValueMapping(Ty.getSizeInBits().getKnownMinValue());
438 OpdsMapping[1] =
440 break;
441 }
442
443 // Try to minimize the number of copies. If we have more floating point
444 // constrained values than not, then we'll put everything on FPR. Otherwise,
445 // everything has to be on GPR.
446 unsigned NumFP = 0;
447
448 // Use FPR64 for s64 select on rv32. An s64 select is only legal here when
449 // D is present (see the G_SELECT rules), so this cannot be a Zilsd i64,
450 // which would need a GPRPair instead.
451 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
452 NumFP = 3;
453 } else {
454 // Check if the uses of the result always produce floating point values.
455 //
456 // For example:
457 //
458 // %z = G_SELECT %cond %x %y
459 // fpr = G_FOO %z ...
460 if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
461 [&](const MachineInstr &UseMI) {
462 return onlyUsesFP(UseMI, MRI, TRI);
463 }))
464 ++NumFP;
465
466 // Check if the defs of the source values always produce floating point
467 // values.
468 //
469 // For example:
470 //
471 // %x = G_SOMETHING_ALWAYS_FLOAT %a ...
472 // %z = G_SELECT %cond %x %y
473 //
474 // Also check whether or not the sources have already been decided to be
475 // FPR. Keep track of this.
476 //
477 // This doesn't check the condition, since the condition is always an
478 // integer.
479 for (unsigned Idx = 2; Idx < 4; ++Idx) {
480 Register VReg = MI.getOperand(Idx).getReg();
481 MachineInstr *DefMI = MRI.getVRegDef(VReg);
482 if (getRegBank(VReg, MRI, TRI) == &RISCV::FPRBRegBank ||
483 onlyDefinesFP(*DefMI, MRI, TRI))
484 ++NumFP;
485 }
486 }
487
488 // Condition operand is always GPR.
489 OpdsMapping[1] = GPRValueMapping;
490
491 const ValueMapping *Mapping = GPRValueMapping;
492 if (NumFP >= 2)
493 Mapping = getFPValueMapping(Ty.getSizeInBits());
494
495 OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] = Mapping;
496 break;
497 }
498 case RISCV::G_FCVT_W_RV64:
499 case RISCV::G_FCVT_WU_RV64:
500 case RISCV::G_FCVT_X:
501 case RISCV::G_FCVT_XU:
502 case TargetOpcode::G_FPTOSI:
503 case TargetOpcode::G_FPTOUI:
504 case TargetOpcode::G_LROUND:
505 case TargetOpcode::G_LLROUND:
506 case TargetOpcode::G_INTRINSIC_LRINT:
507 case TargetOpcode::G_INTRINSIC_LLRINT:
508 case RISCV::G_FCLASS: {
509 LLT Ty = MRI.getType(MI.getOperand(1).getReg());
510 OpdsMapping[0] = GPRValueMapping;
511 OpdsMapping[1] = getFPValueMapping(Ty.getSizeInBits());
512 break;
513 }
514 case TargetOpcode::G_SITOFP:
515 case TargetOpcode::G_UITOFP: {
516 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
517 OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits());
518 OpdsMapping[1] = GPRValueMapping;
519 break;
520 }
521 case TargetOpcode::G_FCMP: {
522 LLT Ty = MRI.getType(MI.getOperand(2).getReg());
523
524 unsigned Size = Ty.getSizeInBits();
525
526 OpdsMapping[0] = GPRValueMapping;
527 OpdsMapping[2] = OpdsMapping[3] = getFPValueMapping(Size);
528 break;
529 }
530 case TargetOpcode::G_MERGE_VALUES: {
531 // RV32 s64: f64 (D) uses FPR64; i64 (Zilsd without D) uses a GPRPair.
532 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
533 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
535 OpdsMapping[0] = useGPRPairForS64(ST, Ty)
537 : getFPValueMapping(Ty.getSizeInBits());
538 assert((useGPRPairForS64(ST, Ty) || ST.hasStdExtD()) &&
539 "s64 merge without D or Zilsd");
540 OpdsMapping[1] = GPRValueMapping;
541 OpdsMapping[2] = GPRValueMapping;
542 }
543 break;
544 }
545 case TargetOpcode::G_UNMERGE_VALUES: {
546 // RV32 s64: f64 (D) uses FPR64; i64 (Zilsd without D) uses a GPRPair.
547 LLT Ty = MRI.getType(MI.getOperand(2).getReg());
548 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
550 OpdsMapping[2] = useGPRPairForS64(ST, Ty)
552 : getFPValueMapping(Ty.getSizeInBits());
553 assert((useGPRPairForS64(ST, Ty) || ST.hasStdExtD()) &&
554 "s64 unmerge without D or Zilsd");
555 OpdsMapping[0] = GPRValueMapping;
556 OpdsMapping[1] = GPRValueMapping;
557 }
558 break;
559 }
560 case TargetOpcode::G_SPLAT_VECTOR: {
561 OpdsMapping[0] = getVRBValueMapping(MRI.getType(MI.getOperand(0).getReg())
562 .getSizeInBits()
563 .getKnownMinValue());
564
565 LLT ScalarTy = MRI.getType(MI.getOperand(1).getReg());
566 MachineInstr *DefMI = MRI.getVRegDef(MI.getOperand(1).getReg());
567 if ((GPRSize == 32 && ScalarTy.getSizeInBits() == 64) ||
568 onlyDefinesFP(*DefMI, MRI, TRI)) {
569 assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD());
570 OpdsMapping[1] = getFPValueMapping(ScalarTy.getSizeInBits());
571 } else
572 OpdsMapping[1] = GPRValueMapping;
573 break;
574 }
575 case TargetOpcode::G_INTRINSIC: {
576 Intrinsic::ID IntrinsicID = cast<GIntrinsic>(MI).getIntrinsicID();
577
579 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntrinsicID)) {
580 unsigned ScalarIdx = -1;
581 if (II->hasScalarOperand()) {
582 ScalarIdx = II->ScalarOperand + 2;
583 }
584 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
585 const MachineOperand &MO = MI.getOperand(Idx);
586 if (!MO.isReg())
587 continue;
588 LLT Ty = MRI.getType(MO.getReg());
589 if (Ty.isVector()) {
590 OpdsMapping[Idx] =
591 getVRBValueMapping(Ty.getSizeInBits().getKnownMinValue());
592 } else if (II->IsFPIntrinsic && ScalarIdx == Idx) {
593 // Chose the right FPR for scalar operand of RVV intrinsics.
594 OpdsMapping[Idx] = getFPValueMapping(Ty.getSizeInBits());
595 } else {
596 OpdsMapping[Idx] = GPRValueMapping;
597 }
598 }
599 }
600
601 if (IntrinsicID == Intrinsic::riscv_orc_b ||
602 IntrinsicID == Intrinsic::riscv_vsetvli ||
603 IntrinsicID == Intrinsic::riscv_vsetvlimax) {
604 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
605 const MachineOperand &MO = MI.getOperand(Idx);
606 if (!MO.isReg())
607 continue;
608 OpdsMapping[Idx] = GPRValueMapping;
609 }
610 }
611 break;
612 }
613 default:
614 // By default map all scalars to GPR.
615 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
616 auto &MO = MI.getOperand(Idx);
617 if (!MO.isReg() || !MO.getReg())
618 continue;
619 LLT Ty = MRI.getType(MO.getReg());
620 if (!Ty.isValid())
621 continue;
622
623 if (Ty.isVector())
624 OpdsMapping[Idx] =
625 getVRBValueMapping(Ty.getSizeInBits().getKnownMinValue());
627 OpdsMapping[Idx] = getFPValueMapping(Ty.getSizeInBits());
628 else
629 OpdsMapping[Idx] = GPRValueMapping;
630 }
631 break;
632 }
633
634 return getInstructionMapping(DefaultMappingID, /*Cost=*/1,
635 getOperandsMapping(OpdsMapping), NumOperands);
636}
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...
IRTranslator LLVM IR MI
Register const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
MachineRegisterInfo & MRI
static const RegisterBankInfo::ValueMapping * getFPValueMapping(unsigned Size)
static const RegisterBankInfo::ValueMapping * getVRBValueMapping(unsigned Size)
static bool useGPRPairForS64(const RISCVSubtarget &ST, LLT Ty)
Decide whether an s64 value on RV32 belongs in a GPRPair (an i64, needs Zilsd) rather than in FPR64 (...
This file declares the targeting of the RegisterBankInfo class for RISC-V.
static bool getUseExtended()
constexpr bool isVector() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
unsigned getID() const
getID() - Return the register class ID number.
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,...
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT Ty) const override
Get a register bank that covers RC.
const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override
Get the mapping of the different operands of MI on the register bank.
unsigned getXLen() const
const RISCVRegisterInfo * getRegisterInfo() const override
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.
virtual const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT Ty) const
Get a register bank that covers RC.
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.
This class implements the register bank concept.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
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...
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:166
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const RegisterBankInfo::PartialMapping PartMappings[]
const RegisterBankInfo::ValueMapping ValueMappings[]
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.
Definition STLExtras.h:1762
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI bool isPreISelGenericFloatingPointOpcode(unsigned Opc)
Returns whether opcode Opc is a pre-isel generic floating-point opcode, having only floating-point op...
Definition Utils.cpp:1701
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
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.