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,
163 const MachineRegisterInfo &MRI,
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_FCLASS:
169 case TargetOpcode::G_FPTOSI:
170 case TargetOpcode::G_FPTOUI:
171 case TargetOpcode::G_LROUND:
172 case TargetOpcode::G_LLROUND:
173 case TargetOpcode::G_INTRINSIC_LRINT:
174 case TargetOpcode::G_INTRINSIC_LLRINT:
175 case TargetOpcode::G_FCMP:
176 return true;
177 default:
178 break;
179 }
180
181 return hasFPConstraints(MI, MRI, TRI);
182}
183
184bool RISCVRegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,
185 const MachineRegisterInfo &MRI,
186 const TargetRegisterInfo &TRI) const {
187 switch (MI.getOpcode()) {
188 case TargetOpcode::G_SITOFP:
189 case TargetOpcode::G_UITOFP:
190 return true;
191 default:
192 break;
193 }
194
195 return hasFPConstraints(MI, MRI, TRI);
196}
197
198bool RISCVRegisterBankInfo::anyUseOnlyUseFP(
199 Register Def, const MachineRegisterInfo &MRI,
200 const TargetRegisterInfo &TRI) const {
201 return any_of(
202 MRI.use_nodbg_instructions(Def),
203 [&](const MachineInstr &UseMI) { return onlyUsesFP(UseMI, MRI, TRI); });
204}
205
207 unsigned Idx;
208
209 if (Size <= 64)
210 Idx = RISCV::VRB64Idx;
211 else if (Size == 128)
212 Idx = RISCV::VRB128Idx;
213 else if (Size == 256)
214 Idx = RISCV::VRB256Idx;
215 else if (Size == 512)
216 Idx = RISCV::VRB512Idx;
217 else
218 llvm::report_fatal_error("Invalid Size");
219
220 return &RISCV::ValueMappings[Idx];
221}
222
225 const unsigned Opc = MI.getOpcode();
226
227 // Try the default logic for non-generic instructions that are either copies
228 // or already have some operands assigned to banks.
229 if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {
230 const InstructionMapping &Mapping = getInstrMappingImpl(MI);
231 if (Mapping.isValid())
232 return Mapping;
233 }
234
235 const MachineFunction &MF = *MI.getParent()->getParent();
236 const MachineRegisterInfo &MRI = MF.getRegInfo();
237 const RISCVSubtarget &Subtarget = MF.getSubtarget<RISCVSubtarget>();
238 const TargetRegisterInfo &TRI = *Subtarget.getRegisterInfo();
239
240 unsigned GPRSize = Subtarget.getXLen();
241
242 unsigned NumOperands = MI.getNumOperands();
243 const ValueMapping *GPRValueMapping =
246
247 switch (Opc) {
248 case TargetOpcode::G_ADD:
249 case TargetOpcode::G_SUB:
250 case TargetOpcode::G_SHL:
251 case TargetOpcode::G_ASHR:
252 case TargetOpcode::G_LSHR:
253 case TargetOpcode::G_AND:
254 case TargetOpcode::G_OR:
255 case TargetOpcode::G_XOR:
256 case TargetOpcode::G_MUL:
257 case TargetOpcode::G_SDIV:
258 case TargetOpcode::G_SREM:
259 case TargetOpcode::G_SMULH:
260 case TargetOpcode::G_SMAX:
261 case TargetOpcode::G_SMIN:
262 case TargetOpcode::G_UDIV:
263 case TargetOpcode::G_UREM:
264 case TargetOpcode::G_UMULH:
265 case TargetOpcode::G_UMAX:
266 case TargetOpcode::G_UMIN:
267 case TargetOpcode::G_PTR_ADD:
268 case TargetOpcode::G_PTRTOINT:
269 case TargetOpcode::G_INTTOPTR:
270 case TargetOpcode::G_FADD:
271 case TargetOpcode::G_FSUB:
272 case TargetOpcode::G_FMUL:
273 case TargetOpcode::G_FDIV:
274 case TargetOpcode::G_FABS:
275 case TargetOpcode::G_FNEG:
276 case TargetOpcode::G_FSQRT:
277 case TargetOpcode::G_FMAXNUM:
278 case TargetOpcode::G_FMINNUM: {
279 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
280 TypeSize Size = Ty.getSizeInBits();
281
282 const ValueMapping *Mapping;
283 if (Ty.isVector())
284 Mapping = getVRBValueMapping(Size.getKnownMinValue());
286 Mapping = getFPValueMapping(Size.getFixedValue());
287 else
288 Mapping = GPRValueMapping;
289
290#ifndef NDEBUG
291 // Make sure all the operands are using similar size and type.
292 for (unsigned Idx = 1; Idx != NumOperands; ++Idx) {
293 LLT OpTy = MRI.getType(MI.getOperand(Idx).getReg());
294 assert(Ty.isVector() == OpTy.isVector() &&
295 "Operand has incompatible type");
296 // Don't check size for GPR.
298 assert(Size == OpTy.getSizeInBits() && "Operand has incompatible size");
299 }
300#endif // End NDEBUG
301
302 return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands);
303 }
304 case TargetOpcode::G_SEXTLOAD:
305 case TargetOpcode::G_ZEXTLOAD:
306 return getInstructionMapping(DefaultMappingID, /*Cost=*/1, GPRValueMapping,
307 NumOperands);
308 case TargetOpcode::G_IMPLICIT_DEF: {
309 Register Dst = MI.getOperand(0).getReg();
310 LLT DstTy = MRI.getType(Dst);
311 unsigned DstMinSize = DstTy.getSizeInBits().getKnownMinValue();
312 auto Mapping = GPRValueMapping;
313 // FIXME: May need to do a better job determining when to use FPRB.
314 // For example, the look through COPY case:
315 // %0:_(s32) = G_IMPLICIT_DEF
316 // %1:_(s32) = COPY %0
317 // $f10_d = COPY %1(s32)
318 if (DstTy.isVector())
319 Mapping = getVRBValueMapping(DstMinSize);
320 else if (anyUseOnlyUseFP(Dst, MRI, TRI))
321 Mapping = getFPValueMapping(DstMinSize);
322
323 return getInstructionMapping(DefaultMappingID, /*Cost=*/1, Mapping,
324 NumOperands);
325 }
326 }
327
328 SmallVector<const ValueMapping *, 4> OpdsMapping(NumOperands);
329
330 switch (Opc) {
331 case TargetOpcode::G_LOAD: {
332 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
333 TypeSize Size = Ty.getSizeInBits();
334
335 OpdsMapping[1] = GPRValueMapping;
336
337 if (Ty.isVector()) {
338 OpdsMapping[0] = getVRBValueMapping(Size.getKnownMinValue());
339 break;
340 }
341
342 OpdsMapping[0] = GPRValueMapping;
343
344 // Atomics always use GPR destinations. Don't refine any further.
345 if (cast<GLoad>(MI).isAtomic())
346 break;
347
348 // Use FPR64 for s64 loads on rv32.
349 if (GPRSize == 32 && Size.getFixedValue() == 64) {
350 assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD());
351 OpdsMapping[0] = getFPValueMapping(Size);
352 break;
353 }
354
355 // Check if that load feeds fp instructions.
356 // In that case, we want the default mapping to be on FPR
357 // instead of blind map every scalar to GPR.
358 if (anyUseOnlyUseFP(MI.getOperand(0).getReg(), MRI, TRI)) {
359 // If we have at least one direct use in a FP instruction,
360 // assume this was a floating point load in the IR. If it was
361 // not, we would have had a bitcast before reaching that
362 // instruction.
363 OpdsMapping[0] = getFPValueMapping(Size);
364 break;
365 }
366
367 break;
368 }
369 case TargetOpcode::G_STORE: {
370 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
371 TypeSize Size = Ty.getSizeInBits();
372
373 OpdsMapping[1] = GPRValueMapping;
374
375 if (Ty.isVector()) {
376 OpdsMapping[0] = getVRBValueMapping(Size.getKnownMinValue());
377 break;
378 }
379
380 OpdsMapping[0] = GPRValueMapping;
381
382 // Atomics always use GPR sources. Don't refine any further.
383 if (cast<GStore>(MI).isAtomic())
384 break;
385
386 // Use FPR64 for s64 stores on rv32.
387 if (GPRSize == 32 && Size.getFixedValue() == 64) {
388 assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD());
389 OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits());
390 break;
391 }
392
393 MachineInstr *DefMI = MRI.getVRegDef(MI.getOperand(0).getReg());
394 if (onlyDefinesFP(*DefMI, MRI, TRI))
395 OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits());
396 break;
397 }
398 case TargetOpcode::G_SELECT: {
399 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
400
401 if (Ty.isVector()) {
402 auto &Sel = cast<GSelect>(MI);
403 LLT TestTy = MRI.getType(Sel.getCondReg());
404 assert(TestTy.isVector() && "Unexpected condition argument type");
405 OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] =
406 getVRBValueMapping(Ty.getSizeInBits().getKnownMinValue());
407 OpdsMapping[1] =
409 break;
410 }
411
412 // Try to minimize the number of copies. If we have more floating point
413 // constrained values than not, then we'll put everything on FPR. Otherwise,
414 // everything has to be on GPR.
415 unsigned NumFP = 0;
416
417 // Use FPR64 for s64 select on rv32.
418 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
419 NumFP = 3;
420 } else {
421 // Check if the uses of the result always produce floating point values.
422 //
423 // For example:
424 //
425 // %z = G_SELECT %cond %x %y
426 // fpr = G_FOO %z ...
427 if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
428 [&](const MachineInstr &UseMI) {
429 return onlyUsesFP(UseMI, MRI, TRI);
430 }))
431 ++NumFP;
432
433 // Check if the defs of the source values always produce floating point
434 // values.
435 //
436 // For example:
437 //
438 // %x = G_SOMETHING_ALWAYS_FLOAT %a ...
439 // %z = G_SELECT %cond %x %y
440 //
441 // Also check whether or not the sources have already been decided to be
442 // FPR. Keep track of this.
443 //
444 // This doesn't check the condition, since the condition is always an
445 // integer.
446 for (unsigned Idx = 2; Idx < 4; ++Idx) {
447 Register VReg = MI.getOperand(Idx).getReg();
448 MachineInstr *DefMI = MRI.getVRegDef(VReg);
449 if (getRegBank(VReg, MRI, TRI) == &RISCV::FPRBRegBank ||
450 onlyDefinesFP(*DefMI, MRI, TRI))
451 ++NumFP;
452 }
453 }
454
455 // Condition operand is always GPR.
456 OpdsMapping[1] = GPRValueMapping;
457
458 const ValueMapping *Mapping = GPRValueMapping;
459 if (NumFP >= 2)
460 Mapping = getFPValueMapping(Ty.getSizeInBits());
461
462 OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] = Mapping;
463 break;
464 }
465 case RISCV::G_FCVT_W_RV64:
466 case RISCV::G_FCVT_WU_RV64:
467 case TargetOpcode::G_FPTOSI:
468 case TargetOpcode::G_FPTOUI:
469 case TargetOpcode::G_LROUND:
470 case TargetOpcode::G_LLROUND:
471 case TargetOpcode::G_INTRINSIC_LRINT:
472 case TargetOpcode::G_INTRINSIC_LLRINT:
473 case RISCV::G_FCLASS: {
474 LLT Ty = MRI.getType(MI.getOperand(1).getReg());
475 OpdsMapping[0] = GPRValueMapping;
476 OpdsMapping[1] = getFPValueMapping(Ty.getSizeInBits());
477 break;
478 }
479 case TargetOpcode::G_SITOFP:
480 case TargetOpcode::G_UITOFP: {
481 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
482 OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits());
483 OpdsMapping[1] = GPRValueMapping;
484 break;
485 }
486 case TargetOpcode::G_FCMP: {
487 LLT Ty = MRI.getType(MI.getOperand(2).getReg());
488
489 unsigned Size = Ty.getSizeInBits();
490
491 OpdsMapping[0] = GPRValueMapping;
492 OpdsMapping[2] = OpdsMapping[3] = getFPValueMapping(Size);
493 break;
494 }
495 case TargetOpcode::G_MERGE_VALUES: {
496 // Use FPR64 for s64 merge on rv32.
497 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
498 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
499 assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD());
500 OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits());
501 OpdsMapping[1] = GPRValueMapping;
502 OpdsMapping[2] = GPRValueMapping;
503 }
504 break;
505 }
506 case TargetOpcode::G_UNMERGE_VALUES: {
507 // Use FPR64 for s64 unmerge on rv32.
508 LLT Ty = MRI.getType(MI.getOperand(2).getReg());
509 if (GPRSize == 32 && Ty.getSizeInBits() == 64) {
510 assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD());
511 OpdsMapping[0] = GPRValueMapping;
512 OpdsMapping[1] = GPRValueMapping;
513 OpdsMapping[2] = getFPValueMapping(Ty.getSizeInBits());
514 }
515 break;
516 }
517 case TargetOpcode::G_SPLAT_VECTOR: {
518 OpdsMapping[0] = getVRBValueMapping(MRI.getType(MI.getOperand(0).getReg())
521
522 LLT ScalarTy = MRI.getType(MI.getOperand(1).getReg());
523 MachineInstr *DefMI = MRI.getVRegDef(MI.getOperand(1).getReg());
524 if ((GPRSize == 32 && ScalarTy.getSizeInBits() == 64) ||
525 onlyDefinesFP(*DefMI, MRI, TRI)) {
526 assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD());
527 OpdsMapping[1] = getFPValueMapping(ScalarTy.getSizeInBits());
528 } else
529 OpdsMapping[1] = GPRValueMapping;
530 break;
531 }
532 case TargetOpcode::G_INTRINSIC: {
533 Intrinsic::ID IntrinsicID = cast<GIntrinsic>(MI).getIntrinsicID();
534
536 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntrinsicID)) {
537 unsigned ScalarIdx = -1;
538 if (II->hasScalarOperand()) {
539 ScalarIdx = II->ScalarOperand + 2;
540 }
541 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
542 const MachineOperand &MO = MI.getOperand(Idx);
543 if (!MO.isReg())
544 continue;
545 LLT Ty = MRI.getType(MO.getReg());
546 if (Ty.isVector()) {
547 OpdsMapping[Idx] =
548 getVRBValueMapping(Ty.getSizeInBits().getKnownMinValue());
549 } else if (II->IsFPIntrinsic && ScalarIdx == Idx) {
550 // Chose the right FPR for scalar operand of RVV intrinsics.
551 OpdsMapping[Idx] = getFPValueMapping(Ty.getSizeInBits());
552 } else {
553 OpdsMapping[Idx] = GPRValueMapping;
554 }
555 }
556 }
557
558 if (IntrinsicID == Intrinsic::riscv_vsetvli ||
559 IntrinsicID == Intrinsic::riscv_vsetvlimax) {
560 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
561 const MachineOperand &MO = MI.getOperand(Idx);
562 if (!MO.isReg())
563 continue;
564 OpdsMapping[Idx] = GPRValueMapping;
565 }
566 }
567 break;
568 }
569 default:
570 // By default map all scalars to GPR.
571 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
572 auto &MO = MI.getOperand(Idx);
573 if (!MO.isReg() || !MO.getReg())
574 continue;
575 LLT Ty = MRI.getType(MO.getReg());
576 if (!Ty.isValid())
577 continue;
578
579 if (Ty.isVector())
580 OpdsMapping[Idx] =
581 getVRBValueMapping(Ty.getSizeInBits().getKnownMinValue());
583 OpdsMapping[Idx] = getFPValueMapping(Ty.getSizeInBits());
584 else
585 OpdsMapping[Idx] = GPRValueMapping;
586 }
587 break;
588 }
589
590 return getInstructionMapping(DefaultMappingID, /*Cost=*/1,
591 getOperandsMapping(OpdsMapping), NumOperands);
592}
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
static const RegisterBankInfo::ValueMapping * getFPValueMapping(unsigned Size)
static const RegisterBankInfo::ValueMapping * getVRBValueMapping(unsigned Size)
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.
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,...
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
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:165
#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:1746
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:1694
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.