31 #define GET_TARGET_REGBANK_IMPL 32 #include "AArch64GenRegisterBank.inc" 35 #include "AArch64GenRegisterBankInfo.def" 41 static bool AlreadyInit =
false;
53 assert(&AArch64::GPRRegBank == &RBGPR &&
54 "The order in RegBanks is messed up");
58 assert(&AArch64::FPRRegBank == &RBFPR &&
59 "The order in RegBanks is messed up");
63 assert(&AArch64::CCRegBank == &RBCCR &&
"The order in RegBanks is messed up");
68 "Subclass not added?");
69 assert(RBGPR.
getSize() == 64 &&
"GPRs should hold up to 64-bit");
74 "Subclass not added?");
76 "Subclass not added?");
78 "FPRs should hold up to 512-bit via QQQQ sequence");
82 assert(RBCCR.
getSize() == 32 &&
"CCR should hold up to 32-bit");
88 "PartialMappingIdx's are incorrectly ordered");
92 "PartialMappingIdx's are incorrectly ordered");
95 #define CHECK_PARTIALMAP(Idx, ValStartIdx, ValLength, RB) \ 98 checkPartialMap(PartialMappingIdx::Idx, ValStartIdx, ValLength, RB) && \ 99 #Idx " is incorrectly initialized"); \ 112 #define CHECK_VALUEMAP_IMPL(RBName, Size, Offset) \ 114 assert(checkValueMapImpl(PartialMappingIdx::PMI_##RBName##Size, \ 115 PartialMappingIdx::PMI_First##RBName, Size, \ 117 #RBName #Size " " #Offset " is incorrectly initialized"); \ 120 #define CHECK_VALUEMAP(RBName, Size) CHECK_VALUEMAP_IMPL(RBName, Size, 0) 133 #define CHECK_VALUEMAP_3OPS(RBName, Size) \ 135 CHECK_VALUEMAP_IMPL(RBName, Size, 0); \ 136 CHECK_VALUEMAP_IMPL(RBName, Size, 1); \ 137 CHECK_VALUEMAP_IMPL(RBName, Size, 2); \ 148 #define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size) \ 150 unsigned PartialMapDstIdx = PMI_##RBNameDst##Size - PMI_Min; \ 151 unsigned PartialMapSrcIdx = PMI_##RBNameSrc##Size - PMI_Min; \ 152 (void)PartialMapDstIdx; \ 153 (void)PartialMapSrcIdx; \ 154 const ValueMapping *Map = getCopyMapping( \ 155 AArch64::RBNameDst##RegBankID, AArch64::RBNameSrc##RegBankID, Size); \ 157 assert(Map[0].BreakDown == \ 158 &AArch64GenRegisterBankInfo::PartMappings[PartialMapDstIdx] && \ 159 Map[0].NumBreakDowns == 1 && #RBNameDst #Size \ 160 " Dst is incorrectly initialized"); \ 161 assert(Map[1].BreakDown == \ 162 &AArch64GenRegisterBankInfo::PartMappings[PartialMapSrcIdx] && \ 163 Map[1].NumBreakDowns == 1 && #RBNameSrc #Size \ 164 " Src is incorrectly initialized"); \ 177 #define CHECK_VALUEMAP_FPEXT(DstSize, SrcSize) \ 179 unsigned PartialMapDstIdx = PMI_FPR##DstSize - PMI_Min; \ 180 unsigned PartialMapSrcIdx = PMI_FPR##SrcSize - PMI_Min; \ 181 (void)PartialMapDstIdx; \ 182 (void)PartialMapSrcIdx; \ 183 const ValueMapping *Map = getFPExtMapping(DstSize, SrcSize); \ 185 assert(Map[0].BreakDown == \ 186 &AArch64GenRegisterBankInfo::PartMappings[PartialMapDstIdx] && \ 187 Map[0].NumBreakDowns == 1 && "FPR" #DstSize \ 188 " Dst is incorrectly initialized"); \ 189 assert(Map[1].BreakDown == \ 190 &AArch64GenRegisterBankInfo::PartMappings[PartialMapSrcIdx] && \ 191 Map[1].NumBreakDowns == 1 && "FPR" #SrcSize \ 192 " Src is incorrectly initialized"); \ 201 assert(
verify(TRI) &&
"Invalid register bank information");
206 unsigned Size)
const {
215 if (&A == &AArch64::GPRRegBank && &B == &AArch64::FPRRegBank)
218 if (&A == &AArch64::FPRRegBank && &B == &AArch64::GPRRegBank)
227 switch (RC.
getID()) {
228 case AArch64::FPR8RegClassID:
229 case AArch64::FPR16RegClassID:
230 case AArch64::FPR32RegClassID:
231 case AArch64::FPR64RegClassID:
232 case AArch64::FPR128RegClassID:
233 case AArch64::FPR128_loRegClassID:
234 case AArch64::DDRegClassID:
235 case AArch64::DDDRegClassID:
236 case AArch64::DDDDRegClassID:
237 case AArch64::QQRegClassID:
238 case AArch64::QQQRegClassID:
239 case AArch64::QQQQRegClassID:
241 case AArch64::GPR32commonRegClassID:
242 case AArch64::GPR32RegClassID:
243 case AArch64::GPR32spRegClassID:
244 case AArch64::GPR32sponlyRegClassID:
245 case AArch64::GPR32argRegClassID:
246 case AArch64::GPR32allRegClassID:
247 case AArch64::GPR64commonRegClassID:
248 case AArch64::GPR64RegClassID:
249 case AArch64::GPR64spRegClassID:
250 case AArch64::GPR64sponlyRegClassID:
251 case AArch64::GPR64argRegClassID:
252 case AArch64::GPR64allRegClassID:
253 case AArch64::GPR64noipRegClassID:
254 case AArch64::GPR64common_and_GPR64noipRegClassID:
255 case AArch64::GPR64noip_and_tcGPR64RegClassID:
256 case AArch64::tcGPR64RegClassID:
257 case AArch64::WSeqPairsClassRegClassID:
258 case AArch64::XSeqPairsClassRegClassID:
260 case AArch64::CCRRegClassID:
276 case TargetOpcode::G_OR: {
280 if (Size != 32 && Size != 64)
299 case TargetOpcode::G_BITCAST: {
301 if (Size != 32 && Size != 64)
312 getCopyMapping(AArch64::GPRRegBankID, AArch64::GPRRegBankID, Size),
316 getCopyMapping(AArch64::FPRRegBankID, AArch64::FPRRegBankID, Size),
320 copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
321 getCopyMapping(AArch64::FPRRegBankID, AArch64::GPRRegBankID, Size),
325 copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
326 getCopyMapping(AArch64::GPRRegBankID, AArch64::FPRRegBankID, Size),
335 case TargetOpcode::G_LOAD: {
369 void AArch64RegisterBankInfo::applyMappingImpl(
372 case TargetOpcode::G_OR:
373 case TargetOpcode::G_BITCAST:
374 case TargetOpcode::G_LOAD:
378 "Don't know how to handle that ID");
389 case TargetOpcode::G_FADD:
390 case TargetOpcode::G_FSUB:
391 case TargetOpcode::G_FMUL:
392 case TargetOpcode::G_FMA:
393 case TargetOpcode::G_FDIV:
394 case TargetOpcode::G_FCONSTANT:
395 case TargetOpcode::G_FPEXT:
396 case TargetOpcode::G_FPTRUNC:
397 case TargetOpcode::G_FCEIL:
398 case TargetOpcode::G_FFLOOR:
399 case TargetOpcode::G_FNEARBYINT:
400 case TargetOpcode::G_FNEG:
401 case TargetOpcode::G_FCOS:
402 case TargetOpcode::G_FSIN:
403 case TargetOpcode::G_FLOG10:
404 case TargetOpcode::G_FLOG:
405 case TargetOpcode::G_FLOG2:
406 case TargetOpcode::G_FSQRT:
407 case TargetOpcode::G_FABS:
408 case TargetOpcode::G_FEXP:
409 case TargetOpcode::G_FRINT:
410 case TargetOpcode::G_INTRINSIC_TRUNC:
411 case TargetOpcode::G_INTRINSIC_ROUND:
418 AArch64RegisterBankInfo::getSameKindOfOperandsMapping(
425 assert(NumOperands <= 3 &&
426 "This code is for instructions with 3 or less operands");
443 for (
unsigned Idx = 1; Idx != NumOperands; ++Idx) {
449 "Operand has incompatible size");
452 assert(IsFPR == OpIsFPR &&
"Operand has incompatible type");
454 #endif // End NDEBUG. 460 bool AArch64RegisterBankInfo::hasFPConstraints(
471 if (Op != TargetOpcode::COPY && !MI.
isPHI())
476 &AArch64::FPRRegBank;
479 bool AArch64RegisterBankInfo::onlyUsesFP(
const MachineInstr &MI,
483 case TargetOpcode::G_FPTOSI:
484 case TargetOpcode::G_FPTOUI:
485 case TargetOpcode::G_FCMP:
490 return hasFPConstraints(MI, MRI, TRI);
493 bool AArch64RegisterBankInfo::onlyDefinesFP(
497 case TargetOpcode::G_SITOFP:
498 case TargetOpcode::G_UITOFP:
499 case TargetOpcode::G_EXTRACT_VECTOR_ELT:
500 case TargetOpcode::G_INSERT_VECTOR_ELT:
505 return hasFPConstraints(MI, MRI, TRI);
515 Opc == TargetOpcode::G_PHI) {
530 case TargetOpcode::G_ADD:
531 case TargetOpcode::G_SUB:
532 case TargetOpcode::G_GEP:
533 case TargetOpcode::G_MUL:
534 case TargetOpcode::G_SDIV:
535 case TargetOpcode::G_UDIV:
537 case TargetOpcode::G_AND:
538 case TargetOpcode::G_OR:
539 case TargetOpcode::G_XOR:
541 case TargetOpcode::G_FADD:
542 case TargetOpcode::G_FSUB:
543 case TargetOpcode::G_FMUL:
544 case TargetOpcode::G_FDIV:
545 return getSameKindOfOperandsMapping(MI);
546 case TargetOpcode::G_FPEXT: {
555 case TargetOpcode::G_SHL:
556 case TargetOpcode::G_LSHR:
557 case TargetOpcode::G_ASHR: {
563 return getSameKindOfOperandsMapping(MI);
565 case TargetOpcode::COPY: {
581 assert(DstRB && SrcRB &&
"Both RegBank were nullptr");
592 case TargetOpcode::G_BITCAST: {
599 DstIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
601 SrcIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
606 Opc == TargetOpcode::G_BITCAST ? 2 : 1);
617 for (
unsigned Idx = 0; Idx < NumOperands; ++Idx) {
619 if (!MO.isReg() || !MO.getReg())
638 case TargetOpcode::G_TRUNC: {
644 case TargetOpcode::G_SITOFP:
645 case TargetOpcode::G_UITOFP:
650 case TargetOpcode::G_FPTOSI:
651 case TargetOpcode::G_FPTOUI:
656 case TargetOpcode::G_FCMP:
660 case TargetOpcode::G_BITCAST:
662 if (OpRegBankIdx[0] != OpRegBankIdx[1])
668 case TargetOpcode::G_LOAD:
675 if (OpRegBankIdx[0] != PMI_FirstGPR)
687 if (onlyUsesFP(
UseMI, MRI, TRI)) {
693 case TargetOpcode::G_STORE:
695 if (OpRegBankIdx[0] == PMI_FirstGPR) {
700 if (onlyDefinesFP(*DefMI, MRI, TRI))
705 case TargetOpcode::G_SELECT: {
707 if (OpRegBankIdx[0] != PMI_FirstGPR)
731 [&](
MachineInstr &MI) {
return onlyUsesFP(MI, MRI, TRI); }))
747 for (
unsigned Idx = 2; Idx < 4; ++Idx) {
750 if (
getRegBank(VReg, MRI, TRI) == &AArch64::FPRRegBank ||
751 onlyDefinesFP(*DefMI, MRI, TRI))
762 case TargetOpcode::G_UNMERGE_VALUES: {
765 if (OpRegBankIdx[0] != PMI_FirstGPR)
773 [&](
MachineInstr &MI) {
return onlyUsesFP(MI, MRI, TRI); })) {
776 Idx < NumOperands; ++Idx)
777 OpRegBankIdx[Idx] = PMI_FirstFPR;
781 case TargetOpcode::G_EXTRACT_VECTOR_ELT:
789 case TargetOpcode::G_INSERT_VECTOR_ELT:
802 case TargetOpcode::G_EXTRACT: {
811 case TargetOpcode::G_BUILD_VECTOR:
814 if (OpRegBankIdx[1] != PMI_FirstGPR)
831 for (
unsigned Idx = 0; Idx < NumOperands; ++Idx)
832 OpRegBankIdx[Idx] = PMI_FirstFPR;
839 for (
unsigned Idx = 0; Idx < NumOperands; ++Idx) {
842 if (!Mapping->isValid())
845 OpdsMapping[Idx] = Mapping;
AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
const ValueMapping * getOperandsMapping(Iterator Begin, Iterator End) const
Get the uniquely generated array of ValueMapping for the elements of between Begin and End...
This class represents lattice values for constants.
const InstructionMapping & getInstructionMapping(unsigned ID, unsigned Cost, const ValueMapping *OperandsMapping, unsigned NumOperands) const
Method to get a uniquely generated InstructionMapping.
static const RegisterBankInfo::ValueMapping * getCopyMapping(unsigned DstBankID, unsigned SrcBankID, unsigned Size)
Get the pointer to the ValueMapping of the operands of a copy instruction from the SrcBankID register...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
class llvm::RegisterBankInfo GPR
unsigned getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
Helper class that represents how the value of an instruction may be mapped and what is the related co...
void push_back(const T &Elt)
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
static bool checkPartialMappingIdx(PartialMappingIdx FirstAlias, PartialMappingIdx LastAlias, ArrayRef< PartialMappingIdx > Order)
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
Helper class used to get/create the virtual registers that will be used to replace the MachineOperand...
#define CHECK_VALUEMAP(RBName, Size)
unsigned const TargetRegisterInfo * TRI
LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
const TargetRegisterClass * getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
bool covers(const TargetRegisterClass &RC) const
Check whether this register bank covers RC.
This file declares the targeting of the RegisterBankInfo class for AArch64.
static RegisterBankInfo::ValueMapping ValMappings[]
unsigned getNumOperands() const
Retuns the total number of operands.
const InstructionMapping & getInstrMapping() const
The final mapping of the instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
unsigned getID() const
Return the register class ID number.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
#define CHECK_VALUEMAP_3OPS(RBName, Size)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX...
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
#define CHECK_VALUEMAP_FPEXT(DstSize, SrcSize)
static const RegisterBankInfo::ValueMapping * getFPExtMapping(unsigned DstSize, unsigned SrcSize)
Get the instruction mapping for G_FPEXT.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned const MachineRegisterInfo * MRI
const InstructionMapping & getInvalidInstructionMapping() const
Method to get a uniquely generated invalid InstructionMapping.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineInstrBuilder & UseMI
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
static const unsigned DefaultMappingID
Identifier used when the related instruction mapping instance is generated by target independent code...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static bool isPreISelGenericFloatingPointOpcode(unsigned Opc)
Returns whether opcode Opc is a pre-isel generic floating-point opcode, having only floating-point op...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool verify(const TargetRegisterInfo &TRI) const
Check that information hold by this instance make sense for the given TRI.
bool isValid() const
Check whether this object is valid.
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static void applyDefaultMapping(const OperandsMapper &OpdMapper)
Helper method to apply something that is like the default mapping.
MachineInstr & getMI() const
MachineInstrBuilder MachineInstrBuilder & DefMI
InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const override
Get the alternative mappings for MI.
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
unsigned copyCost(const RegisterBank &A, const RegisterBank &B, unsigned Size) const override
Get the cost of a copy from B to A, or put differently, get the cost of A = COPY B.
#define CHECK_PARTIALMAP(Idx, ValStartIdx, ValLength, RB)
static unsigned getRegBankBaseIdxOffset(unsigned RBIdx, unsigned Size)
This class implements the register bank concept.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
unsigned getID() const
Get the ID.
static const RegisterBankInfo::ValueMapping * getValueMapping(PartialMappingIdx RBIdx, unsigned Size)
Get the pointer to the ValueMapping representing the RegisterBank at RBIdx with a size of Size...
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
TargetSubtargetInfo - Generic base class for all target subtargets.
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override
Get the mapping of the different operands of MI on the register bank.
virtual InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const
Get the alternative mappings for MI.
virtual unsigned copyCost(const RegisterBank &A, const RegisterBank &B, unsigned Size) const
Get the cost of a copy from B to A, or put differently, get the cost of A = COPY B.
const InstructionMapping & getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
iterator_range< use_instr_iterator > use_instructions(unsigned Reg) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getSize() const
Get the maximal size in bits that fits in this register bank.
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel...
#define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size)
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Register getReg() const
getReg - Returns the register number.
const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC) const override
Get a register bank that covers RC.
const MachineOperand & getOperand(unsigned i) const
static RegisterBankInfo::PartialMapping PartMappings[]
Wrapper class representing virtual and physical registers.
unsigned getID() const
Get the identifier of this register bank.