Go to the documentation of this file.
35 #define GET_REGINFO_TARGET_DESC
36 #include "AArch64GenRegisterInfo.inc"
49 unsigned &RegToUseForCFI)
const {
54 RegToUseForCFI = getSubReg(
Reg, AArch64::dsub);
55 for (
int I = 0; CSR_AArch64_AAPCS_SaveList[
I]; ++
I) {
56 if (CSR_AArch64_AAPCS_SaveList[
I] == RegToUseForCFI)
68 return isa<ScalableVectorType>(
F.getReturnType()) ||
70 return isa<ScalableVectorType>(Arg.getType());
76 assert(MF &&
"Invalid MachineFunction pointer.");
81 return CSR_AArch64_NoRegs_SaveList;
83 return CSR_AArch64_AllRegs_SaveList;
91 return CSR_Win_AArch64_CFGuard_Check_SaveList;
93 return CSR_Win_AArch64_AAPCS_SaveList;
95 return CSR_AArch64_AAVPCS_SaveList;
97 return CSR_AArch64_SVE_AAPCS_SaveList;
101 Attribute::SwiftError))
102 return CSR_AArch64_AAPCS_SwiftError_SaveList;
104 return CSR_AArch64_RT_MostRegs_SaveList;
108 return CSR_AArch64_AAPCS_X18_SaveList;
110 return CSR_AArch64_SVE_AAPCS_SaveList;
111 return CSR_AArch64_AAPCS_SaveList;
116 assert(MF &&
"Invalid MachineFunction pointer.");
118 "Invalid subtarget for getDarwinCalleeSavedRegs");
122 "Calling convention CFGuard_Check is unsupported on Darwin.");
124 return CSR_Darwin_AArch64_AAVPCS_SaveList;
127 "Calling convention SVE_VectorCall is unsupported on Darwin.");
130 ? CSR_Darwin_AArch64_CXX_TLS_PE_SaveList
131 : CSR_Darwin_AArch64_CXX_TLS_SaveList;
135 Attribute::SwiftError))
136 return CSR_Darwin_AArch64_AAPCS_SwiftError_SaveList;
138 return CSR_Darwin_AArch64_RT_MostRegs_SaveList;
139 return CSR_Darwin_AArch64_AAPCS_SaveList;
144 assert(MF &&
"Invalid MachineFunction pointer.");
147 return CSR_Darwin_AArch64_CXX_TLS_ViaCopy_SaveList;
156 UpdatedCSRs.push_back(*
I);
158 for (
size_t i = 0;
i < AArch64::GPR64commonRegClass.getNumRegs(); ++
i) {
160 UpdatedCSRs.push_back(AArch64::GPR64commonRegClass.getRegister(
i));
164 UpdatedCSRs.push_back(0);
170 unsigned Idx)
const {
172 if (RC == &AArch64::GPR32allRegClass && Idx == AArch64::hsub)
173 return &AArch64::FPR32RegClass;
174 else if (RC == &AArch64::GPR64allRegClass && Idx == AArch64::hsub)
175 return &AArch64::FPR64RegClass;
178 return AArch64GenRegisterInfo::getSubClassWithSubReg(RC, Idx);
185 "Invalid subtarget for getDarwinCallPreservedMask");
188 return CSR_Darwin_AArch64_CXX_TLS_RegMask;
190 return CSR_Darwin_AArch64_AAVPCS_RegMask;
193 "Calling convention SVE_VectorCall is unsupported on Darwin.");
196 "Calling convention CFGuard_Check is unsupported on Darwin.");
201 return CSR_Darwin_AArch64_AAPCS_SwiftError_RegMask;
203 return CSR_Darwin_AArch64_RT_MostRegs_RegMask;
204 return CSR_Darwin_AArch64_AAPCS_RegMask;
213 return SCS ? CSR_AArch64_NoRegs_SCS_RegMask : CSR_AArch64_NoRegs_RegMask;
215 return SCS ? CSR_AArch64_AllRegs_SCS_RegMask : CSR_AArch64_AllRegs_RegMask;
225 return SCS ? CSR_AArch64_AAVPCS_SCS_RegMask : CSR_AArch64_AAVPCS_RegMask;
227 return SCS ? CSR_AArch64_SVE_AAPCS_SCS_RegMask
228 : CSR_AArch64_SVE_AAPCS_RegMask;
230 return CSR_Win_AArch64_CFGuard_Check_RegMask;
234 return SCS ? CSR_AArch64_AAPCS_SwiftError_SCS_RegMask
235 : CSR_AArch64_AAPCS_SwiftError_RegMask;
237 return SCS ? CSR_AArch64_RT_MostRegs_SCS_RegMask
238 : CSR_AArch64_RT_MostRegs_RegMask;
240 return SCS ? CSR_AArch64_AAPCS_SCS_RegMask : CSR_AArch64_AAPCS_RegMask;
246 return CSR_AArch64_AAPCS_RegMask;
253 return CSR_Darwin_AArch64_TLS_RegMask;
256 return CSR_AArch64_TLS_ELF_RegMask;
263 memcpy(UpdatedMask, *
Mask,
sizeof(UpdatedMask[0]) * RegMaskSize);
265 for (
size_t i = 0;
i < AArch64::GPR64commonRegClass.getNumRegs(); ++
i) {
280 return CSR_AArch64_NoRegs_RegMask;
295 return CSR_Darwin_AArch64_AAPCS_ThisReturn_RegMask;
296 return CSR_AArch64_AAPCS_ThisReturn_RegMask;
300 return CSR_AArch64_StackProbe_Windows_RegMask;
309 markSuperRegs(
Reserved, AArch64::WSP);
310 markSuperRegs(
Reserved, AArch64::WZR);
313 markSuperRegs(
Reserved, AArch64::W29);
315 for (
size_t i = 0;
i < AArch64::GPR32commonRegClass.getNumRegs(); ++
i) {
317 markSuperRegs(
Reserved, AArch64::GPR32commonRegClass.getRegister(
i));
321 markSuperRegs(
Reserved, AArch64::W19);
325 markSuperRegs(
Reserved, AArch64::W16);
346 " function calls if any of the argument registers is reserved.")});
355 return PhysReg == AArch64::WZR || PhysReg == AArch64::XZR;
360 unsigned Kind)
const {
361 return &AArch64::GPR64spRegClass;
366 if (RC == &AArch64::CCRRegClass)
367 return &AArch64::GPR64RegClass;
385 if (hasStackRealignment(MF))
412 return TFI->
hasFP(MF) ? AArch64::FP : AArch64::SP;
439 "Expected SVE area to be calculated by this point");
462 for (
unsigned i = 0; !
MI->getOperand(
i).isFI(); ++
i)
463 assert(i < MI->getNumOperands() &&
464 "Instr doesn't have FrameIndex operand!");
475 if (!
MI->mayLoad() && !
MI->mayStore())
490 int64_t FPOffset =
Offset - 16 * 20;
527 assert(
MI &&
"Unable to get the legal offset for nil instruction.");
541 DL =
Ins->getDebugLoc();
565 while (!
MI.getOperand(
i).isFI()) {
567 assert(
i <
MI.getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
574 assert(Done &&
"Unable to resolve frame index!");
587 if (
MI.getOpcode() == AArch64::STGloop) {
588 MI.setDesc(
TII->get(AArch64::STGloop_wback));
589 return MI.getOperand(1).getReg();
590 }
else if (
MI.getOpcode() == AArch64::STZGloop) {
591 MI.setDesc(
TII->get(AArch64::STZGloop_wback));
592 return MI.getOperand(1).getReg();
594 return MI.getMF()->getRegInfo().createVirtualRegister(
595 &AArch64::GPR64RegClass);
604 assert(
Offset.getScalable() % 2 == 0 &&
"Invalid frame offset");
610 int64_t VGSized =
Offset.getScalable() / 2;
612 Ops.push_back(dwarf::DW_OP_constu);
613 Ops.push_back(VGSized);
614 Ops.
append({dwarf::DW_OP_bregx, VG, 0ULL});
615 Ops.push_back(dwarf::DW_OP_mul);
616 Ops.push_back(dwarf::DW_OP_plus);
617 }
else if (VGSized < 0) {
618 Ops.push_back(dwarf::DW_OP_constu);
619 Ops.push_back(-VGSized);
620 Ops.
append({dwarf::DW_OP_bregx, VG, 0ULL});
621 Ops.push_back(dwarf::DW_OP_mul);
622 Ops.push_back(dwarf::DW_OP_minus);
627 int SPAdj,
unsigned FIOperandNum,
629 assert(SPAdj == 0 &&
"Unexpected");
638 int FrameIndex =
MI.getOperand(FIOperandNum).getIndex();
644 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
645 MI.getOpcode() == TargetOpcode::PATCHPOINT ||
646 MI.getOpcode() == TargetOpcode::STATEPOINT) {
652 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg,
false );
653 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(
Offset.getFixed());
657 if (
MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE) {
661 "Frame offsets with a scalable component are not supported");
667 if (
MI.getOpcode() == AArch64::TAGPstack) {
670 FrameReg =
MI.getOperand(3).getReg();
691 MI.getOperand(FIOperandNum)
692 .ChangeToRegister(ScratchReg,
false,
false,
true);
695 FrameReg = AArch64::SP;
708 "Emergency spill slot is out of reach");
715 MI.getOperand(FIOperandNum).ChangeToRegister(ScratchReg,
false,
false,
true);
722 switch (RC->
getID()) {
725 case AArch64::GPR32RegClassID:
726 case AArch64::GPR32spRegClassID:
727 case AArch64::GPR32allRegClassID:
728 case AArch64::GPR64spRegClassID:
729 case AArch64::GPR64allRegClassID:
730 case AArch64::GPR64RegClassID:
731 case AArch64::GPR32commonRegClassID:
732 case AArch64::GPR64commonRegClassID:
737 case AArch64::FPR8RegClassID:
738 case AArch64::FPR16RegClassID:
739 case AArch64::FPR32RegClassID:
740 case AArch64::FPR64RegClassID:
741 case AArch64::FPR128RegClassID:
744 case AArch64::DDRegClassID:
745 case AArch64::DDDRegClassID:
746 case AArch64::DDDDRegClassID:
747 case AArch64::QQRegClassID:
748 case AArch64::QQQRegClassID:
749 case AArch64::QQQQRegClassID:
752 case AArch64::FPR128_loRegClassID:
753 case AArch64::FPR64_loRegClassID:
754 case AArch64::FPR16_loRegClassID:
764 else if (hasStackRealignment(MF))
775 ((DstRC->
getID() == AArch64::GPR64RegClassID) ||
776 (DstRC->
getID() == AArch64::GPR64commonRegClassID)) &&
777 MI->getOperand(0).getSubReg() &&
MI->getOperand(1).getSubReg())
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
This class represents an incoming formal argument to a Function.
bool isTargetWindows() const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
unsigned getID() const
Return the register class ID number.
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg, const TargetRegisterClass *DstRC, unsigned DstSubReg, const TargetRegisterClass *NewRC, LiveIntervals &LIS) const override
SrcRC and DstRC will be morphed into NewRC if this returns true.
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index=nullptr) const
Return true if the specified attribute is set for at least one parameter or for the return value.
uint32_t * allocateRegMask()
Allocate and initialize a register mask with NumRegister bits.
Diagnostic information for unsupported feature in backend.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
@ AArch64FrameOffsetCanUpdate
Offset can apply, at least partly.
return AArch64::GPR64RegClass contains(Reg)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void UpdateCustomCallPreservedMask(MachineFunction &MF, const uint32_t **Mask) const
unsigned getBaseRegister() const
bool isAnyArgRegReserved(const MachineFunction &MF) const
const uint32_t * getNoPreservedMask() const override
bool isTargetDarwin() const
const MCPhysReg * getCalleeSavedRegsViaCopy(const MachineFunction *MF) const
Triple - Helper class for working with autoconf configuration names.
static unsigned getDwarfRegNum(unsigned Reg, const TargetRegisterInfo *TRI)
Go up the super-register chain until we hit a valid dwarf register number.
ScalarTy getFixed() const
Register getFrameRegister(const MachineFunction &MF) const override
bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, StackOffset &Offset, const AArch64InstrInfo *TII)
rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the FP.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isXRegCustomCalleeSaved(size_t i) const
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
const AArch64TargetLowering * getTargetLowering() const override
unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const override
bool isScavengingFrameIndex(int FI) const
Query whether a frame index is a scavenging frame index.
bool cannotEliminateFrame(const MachineFunction &MF) const
const TargetRegisterClass * getCrossCopyRegClass(const TargetRegisterClass *RC) const override
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
const TargetRegisterClass * getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const override
static bool hasSVEArgsOrReturn(const MachineFunction *MF)
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (macOS, iOS, tvOS or watchOS).
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
static unsigned getRegMaskSize(unsigned NumRegs)
Returns number of elements needed for a regmask array.
bool supportSwiftError() const override
Return true if the target supports swifterror attribute.
static Register createScratchRegisterForInstruction(MachineInstr &MI, const AArch64InstrInfo *TII)
const HexagonInstrInfo * TII
void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
Describe properties that are true of each instruction in the target description file.
MachineOperand class - Representation of each machine instruction operand.
void setCalleeSavedRegs(ArrayRef< MCPhysReg > CSRs)
Sets the updated Callee Saved Registers list.
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
@ Win64
The C convention as implemented on Windows/x86-64 and AArch64.
Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, int64_t Offset) const override
Insert defining instruction(s) for BaseReg to be a pointer to FrameIdx at the beginning of the basic ...
void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, StackOffset Offset, const TargetInstrInfo *TII, MachineInstr::MIFlag=MachineInstr::NoFlags, bool SetNZCV=false, bool NeedsWinCFI=false, bool *HasWinCFI=nullptr)
emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg plus Offset.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, int64_t Offset) const override
AttributeList getAttributes() const
Return the attribute list for this Function.
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
@ AArch64FrameOffsetIsLegal
Offset is legal.
StackOffset resolveFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg, bool PreferFP, bool ForSimm) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
AArch64RegisterInfo(const Triple &TT)
const MachineInstrBuilder & addFrameIndex(int Idx) const
int isAArch64FrameOffsetLegal(const MachineInstr &MI, StackOffset &Offset, bool *OutUseUnscaledOp=nullptr, unsigned *OutUnscaledOp=nullptr, int64_t *EmittableOffset=nullptr)
Check if the Offset is a valid frame offset for MI.
int64_t getLocalFrameSize() const
Get the size of the local object blob.
Representation of each machine instruction.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
unsigned getTaggedBasePointerOffset() const
@ AArch64_SVE_VectorCall
Calling convention between AArch64 SVE functions.
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override
needsFrameBaseReg - Returns true if the instruction's frame index reference would be better served by...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
bool isConstantPhysReg(MCRegister PhysReg) const override
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
bool isTargetLinux() const
bool useFPForScavengingIndex(const MachineFunction &MF) const override
StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF, int FI) const override
getNonLocalFrameIndexReference - This method returns the offset used to reference a frame index locat...
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
BitVector getReservedRegs(const MachineFunction &MF) const override
bool requiresFrameIndexScavenging(const MachineFunction &MF) const override
bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const override
bool isXRegisterReserved(size_t i) const
unsigned getLocalAddressRegister(const MachineFunction &MF) const
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool hasCalculatedStackSizeSVE() const
StackOffset is a class to represent an offset with 2 dimensions, named fixed and scalable,...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
const uint32_t * getCustomEHPadPreservedMask(const MachineFunction &MF) const override
const uint32_t * getThisReturnPreservedMask(const MachineFunction &MF, CallingConv::ID) const
getThisReturnPreservedMask - Returns a call preserved mask specific to the case that 'returned' is on...
void emitReservedArgRegCallError(const MachineFunction &MF) const
const uint32_t * getDarwinCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
void initLLVMToCVRegMapping(MCRegisterInfo *MRI)
static void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
unsigned getNumXRegisterReserved() const
void getOffsetOpcodes(const StackOffset &Offset, SmallVectorImpl< uint64_t > &Ops) const override
Function & getFunction()
Return the LLVM function that this machine code represents.
uint64_t getStackSizeSVE() const
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const uint32_t * getWindowsStackProbePreservedMask() const
Stack probing calls preserve different CSRs to the normal CC.
bool hasEHFunclets() const
MCSubRegIterator enumerates all sub-registers of Reg.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void resolveFrameIndex(MachineInstr &MI, Register BaseReg, int64_t Offset) const override
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override
const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
void UpdateCustomCalleeSavedRegs(MachineFunction &MF) const
const uint32_t * getTLSCallPreservedMask() const
bool regNeedsCFI(unsigned Reg, unsigned &RegToUseForCFI) const
Return whether the register needs a CFI entry.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
@ MO_TAGGED
MO_TAGGED - With MO_PAGE, indicates that the page includes a memory tag in bits 56-63.
bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override
bool hasBasePointer(const MachineFunction &MF) const
bool requiresRegisterScavenging(const MachineFunction &MF) const override
const MCPhysReg * getDarwinCalleeSavedRegs(const MachineFunction *MF) const
bool isReservedReg(const MachineFunction &MF, MCRegister Reg) const
Wrapper class representing physical registers. Should be passed by value.