Go to the documentation of this file.
50 #define DEBUG_TYPE "arm-register-info"
52 #define GET_REGINFO_TARGET_DESC
53 #include "ARMGenRegisterInfo.inc"
69 : (UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList);
75 return CSR_NoRegs_SaveList;
77 return CSR_Win_AAPCS_CFGuard_Check_SaveList;
80 ? CSR_iOS_SwiftTail_SaveList
81 : (UseSplitPush ? CSR_AAPCS_SplitPush_SwiftTail_SaveList
82 : CSR_AAPCS_SwiftTail_SaveList);
83 }
else if (
F.hasFnAttribute(
"interrupt")) {
87 return UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList;
88 }
else if (
F.getFnAttribute(
"interrupt").getValueAsString() ==
"FIQ") {
91 return CSR_FIQ_SaveList;
95 return CSR_GenericInt_SaveList;
100 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError)) {
102 return CSR_iOS_SwiftError_SaveList;
104 return UseSplitPush ? CSR_AAPCS_SplitPush_SwiftError_SaveList :
105 CSR_AAPCS_SwiftError_SaveList;
110 ? CSR_iOS_CXX_TLS_PE_SaveList
111 : CSR_iOS_CXX_TLS_SaveList;
117 assert(MF &&
"Invalid MachineFunction pointer.");
120 return CSR_iOS_CXX_TLS_ViaCopy_SaveList;
130 return CSR_NoRegs_RegMask;
132 return CSR_Win_AAPCS_CFGuard_Check_RegMask;
135 : CSR_AAPCS_SwiftTail_RegMask;
140 : CSR_AAPCS_SwiftError_RegMask;
143 return CSR_iOS_CXX_TLS_RegMask;
144 return STI.
isTargetDarwin() ? CSR_iOS_RegMask : CSR_AAPCS_RegMask;
149 return CSR_NoRegs_RegMask;
155 "only know about special TLS call on Darwin");
156 return CSR_iOS_TLSCall_RegMask;
163 return CSR_NoRegs_RegMask;
165 return CSR_FPRegs_RegMask;
184 : CSR_AAPCS_ThisReturn_RegMask;
189 static const MCPhysReg IntraCallClobberedRegs[] = {ARM::R12};
200 markSuperRegs(Reserved, ARM::SP);
201 markSuperRegs(Reserved, ARM::PC);
202 markSuperRegs(Reserved, ARM::FPSCR);
203 markSuperRegs(Reserved, ARM::APSR_NZCV);
207 markSuperRegs(Reserved,
BasePtr);
210 markSuperRegs(Reserved, ARM::R9);
213 static_assert(ARM::D31 == ARM::D16 + 15,
"Register list not consecutive!");
214 for (
unsigned R = 0; R < 16; ++R)
215 markSuperRegs(Reserved, ARM::D16 + R);
218 for (
unsigned Reg : RC)
221 markSuperRegs(Reserved,
Reg);
223 markSuperRegs(Reserved, ARM::ZR);
225 assert(checkAllSuperRegsMarked(Reserved));
235 unsigned PhysReg)
const {
240 markSuperRegs(Reserved, ARM::PC);
244 markSuperRegs(Reserved,
BasePtr);
245 assert(checkAllSuperRegsMarked(Reserved));
246 return Reserved.
test(PhysReg);
255 switch (Super->
getID()) {
256 case ARM::GPRRegClassID:
257 case ARM::SPRRegClassID:
258 case ARM::DPRRegClassID:
259 case ARM::GPRPairRegClassID:
261 case ARM::QPRRegClassID:
262 case ARM::QQPRRegClassID:
263 case ARM::QQQQPRRegClassID:
267 case ARM::MQPRRegClassID:
268 case ARM::MQQPRRegClassID:
269 case ARM::MQQQQPRRegClassID:
282 return &ARM::GPRRegClass;
287 if (RC == &ARM::CCRRegClass)
288 return &ARM::rGPRRegClass;
298 switch (RC->
getID()) {
301 case ARM::tGPRRegClassID: {
306 ? TFI->hasFP(MF) :
true;
309 case ARM::GPRRegClassID: {
311 ? TFI->hasFP(MF) :
true;
314 case ARM::SPRRegClassID:
315 case ARM::DPRRegClassID:
324 if (ARM::GPRPairRegClass.
contains(*Supers))
325 return RI->
getSubReg(*Supers, Odd ? ARM::gsub_1 : ARM::gsub_0);
338 switch (Hint.first) {
348 Hints.push_back(ARM::LR);
364 }
else if (VRM && VRM->
hasPhys(Paired)) {
370 Hints.push_back(PairedPhys);
374 if (
Reg == PairedPhys || (getEncodingValue(
Reg) & 1) != Odd)
380 Hints.push_back(
Reg);
390 Hint.second.isVirtual()) {
398 if (Hint.second ==
Reg) {
418 if (hasStackRealignment(MF) && !TFI->hasReservedCallFrame(MF))
475 hasStackRealignment(MF);
528 int64_t InstrOffs = 0;
537 InstrOffs =
MI->getOperand(Idx+1).getImm();
545 InstrOffs = -InstrOffs;
553 InstrOffs = -InstrOffs;
559 InstrOffs = -InstrOffs;
563 InstrOffs =
MI->getOperand(ImmIdx).getImm();
570 return InstrOffs * Scale;
579 for (
unsigned i = 0; !
MI->getOperand(
i).isFI(); ++
i) {
580 assert(i < MI->getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
592 unsigned Opc =
MI->getOpcode();
594 case ARM::LDRi12:
case ARM::LDRH:
case ARM::LDRBi12:
595 case ARM::STRi12:
case ARM::STRH:
case ARM::STRBi12:
596 case ARM::t2LDRi12:
case ARM::t2LDRi8:
597 case ARM::t2STRi12:
case ARM::t2STRi8:
598 case ARM::VLDRS:
case ARM::VLDRD:
599 case ARM::VSTRS:
case ARM::VSTRD:
600 case ARM::tSTRspi:
case ARM::tLDRspi:
620 int64_t FPOffset = Offset - 8;
638 if (TFI->
hasFP(MF) &&
661 int64_t Offset)
const {
669 DL =
Ins->getDebugLoc();
688 int64_t Offset)
const {
698 "This resolveFrameIndex does not support Thumb1!");
700 while (!
MI.getOperand(
i).isFI()) {
702 assert(
i <
MI.getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
711 assert(Done &&
"Unable to resolve frame index!");
717 int64_t Offset)
const {
721 for (; !
MI->getOperand(
i).isFI(); ++
i)
722 assert(
i+1 <
MI->getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
728 unsigned NumBits = 0;
730 bool isSigned =
true;
759 NumBits = (BaseReg == ARM::SP ? 8 : 5);
770 if ((Offset & (Scale-1)) != 0)
773 if (isSigned && Offset < 0)
776 unsigned Mask = (1 << NumBits) - 1;
777 if ((
unsigned)Offset <=
Mask * Scale)
785 int SPAdj,
unsigned FIOperandNum,
795 "This eliminateFrameIndex does not support Thumb1!");
796 int FrameIndex =
MI.getOperand(FIOperandNum).getIndex();
808 "Cannot use SP to access the emergency spill slot in "
809 "functions without a reserved call frame");
811 "Cannot use SP to access the emergency spill slot in "
812 "functions with variable sized frame objects");
816 assert(!
MI.isDebugValue() &&
"DBG_VALUEs should be handled in target-independent code");
840 "This code isn't needed if offset already handled!");
842 unsigned ScratchReg = 0;
843 int PIdx =
MI.findFirstPredOperandIdx();
850 TII.getRegClass(MCID, FIOperandNum,
this, *
MI.getParent()->getParent());
855 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg,
false,
false,
false);
860 Offset, Pred, PredReg,
TII);
864 Offset, Pred, PredReg,
TII);
867 MI.getOperand(FIOperandNum).ChangeToRegister(ScratchReg,
false,
false,
true);
878 auto MBB =
MI->getParent();
886 if (getRegSizeInBits(*NewRC) < 256 && getRegSizeInBits(*DstRC) < 256 &&
887 getRegSizeInBits(*SrcRC) < 256)
898 if (SrcRCWeight.RegWeight > NewRCWeight.RegWeight)
900 if (DstRCWeight.RegWeight > NewRCWeight.RegWeight)
911 << It->second <<
"\n");
913 << NewRCWeight.RegWeight <<
"\n");
921 unsigned SizeMultiplier =
MBB->
size()/100;
922 SizeMultiplier = SizeMultiplier ? SizeMultiplier : 1;
923 if (It->second < NewRCWeight.WeightLimit * SizeMultiplier) {
924 It->second += NewRCWeight.RegWeight;
933 unsigned SrcSubReg)
const {
935 if (DefRC == &ARM::SPRRegClass && DefSubReg == 0 &&
936 SrcRC == &ARM::DPRRegClass &&
937 (SrcSubReg == ARM::ssub_0 || SrcSubReg == ARM::ssub_1))
bool isMaxCallFrameSizeComputed() const
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, int64_t Offset) const override
materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to be a pointer to FrameIdx...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
unsigned getID() const
Return the register class ID number.
This is an optimization pass for GlobalISel generic memory operations.
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
const MCPhysReg * getCalleeSavedRegsViaCopy(const MachineFunction *MF) const
unsigned char getAM3Offset(unsigned AM3Opc)
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.
bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, unsigned DefSubReg, const TargetRegisterClass *SrcRC, unsigned SrcSubReg) const override
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const MachineInstrBuilder & add(const MachineOperand &MO) const
const uint32_t * getThisReturnPreservedMask(const MachineFunction &MF, CallingConv::ID) const
getThisReturnPreservedMask - Returns a call preserved mask specific to the case that 'returned' is on...
const TargetRegisterClass * getCrossCopyRegClass(const TargetRegisterClass *RC) const override
virtual const TargetInstrInfo * getInstrInfo() const
void emitT2RegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, ARMCC::CondCodes Pred, Register PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
return AArch64::GPR64RegClass contains(Reg)
bool isThumb1OnlyFunction() const
Reg
All possible values of the reg field in the ModR/M byte.
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override
const TargetRegisterInfo * getTargetRegisterInfo() const
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
bool canReserveReg(MCRegister PhysReg) const
canReserveReg - Returns true if PhysReg can be used as a reserved register.
AddrOpc getAM3Op(unsigned AM3Opc)
bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, int64_t Offset) const override
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
const ARMTargetLowering * getTargetLowering() const override
unsigned getAM2Offset(unsigned AM2Opc)
static MCPhysReg getPairedGPR(MCPhysReg Reg, bool Odd, const MCRegisterInfo *RI)
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
static IntegerType * getInt32Ty(LLVMContext &C)
int64_t getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const override
bool isScavengingFrameIndex(int FI) const
Query whether a frame index is a scavenging frame index.
AddrOpc getAM5Op(unsigned AM5Opc)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool requiresRegisterScavenging(const MachineFunction &MF) const override
Code Generation virtual methods...
constexpr 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.
bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
bool splitFramePushPop(const MachineFunction &MF) const
Returns true if the frame setup is split into two separate pushes (first r0-r7,lr then r8-r11),...
unsigned getDefRegState(bool B)
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
virtual bool canRealignStack(const MachineFunction &MF) const
True if the stack can be realigned for the target.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
TargetInstrInfo - Interface to description of machine instruction set.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
(vector float) vec_cmpeq(*A, *B) C
Register getFrameRegister(const MachineFunction &MF) const override
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
AddrOpc getAM2Op(unsigned AM2Opc)
const HexagonInstrInfo * TII
Describe properties that are true of each instruction in the target description file.
MachineOperand class - Representation of each machine instruction operand.
bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const override
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
bool cannotEliminateFrame(const MachineFunction &MF) const
Align getLocalFrameMaxAlign() const
Return the required alignment of the local object blob.
const uint32_t * getSjLjDispatchPreservedMask(const MachineFunction &MF) const
bool isThumbFunction() const
bool isInlineAsmReadOnlyReg(const MachineFunction &MF, unsigned PhysReg) const override
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
AttributeList getAttributes() const
Return the attribute list for this Function.
bool hasPhys(Register virtReg) const
returns true if the specified virtual register is mapped to a physical register
DenseMap< const MachineBasicBlock *, unsigned >::iterator getCoalescedWeight(MachineBasicBlock *MBB)
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineInstrBuilder & addFrameIndex(int Idx) const
This is an important base class in LLVM.
bool isThumb1Only() const
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...
bool isR9Reserved() const
bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, Register FrameReg, int &Offset, const ARMBaseInstrInfo &TII, const TargetRegisterInfo *TRI)
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
virtual bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM=nullptr, const LiveRegMatrix *Matrix=nullptr) const
Get a list of 'hint' registers that the register allocator should try first when allocating a physica...
MCPhysReg getFramePointerReg() const
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
void initLLVMToCVRegMapping(MCRegisterInfo *MRI)
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
int ResolveFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg, int SPAdj) const
const uint32_t * getNoPreservedMask() const override
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void resolveFrameIndex(MachineInstr &MI, Register BaseReg, int64_t Offset) const override
StandardInstrumentations SI(Debug, VerifyEach)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MCSuperRegIterator enumerates all super-registers of Reg.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const uint32_t * getTLSCallPreservedMask(const MachineFunction &MF) const
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.
bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const override
bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, Register FrameReg, int &Offset, const ARMBaseInstrInfo &TII)
rewriteARMFrameIndex / rewriteT2FrameIndex - Rewrite MI to access 'Offset' bytes from the FP.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override
needsFrameBaseReg - Returns true if the instruction's frame index reference would be better served by...
MachineBasicBlock MachineBasicBlock::iterator MBBI
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setRegAllocationHint(Register VReg, unsigned Type, Register PrefReg)
setRegAllocationHint - Specify a register allocation hint for the specified virtual register.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &MF) const override
BitVector getReservedRegs(const MachineFunction &MF) const override
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
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...
virtual bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, unsigned DefSubReg, const TargetRegisterClass *SrcRC, unsigned SrcSubReg) const
bool requiresFrameIndexScavenging(const MachineFunction &MF) const override
bool test(unsigned Idx) const
Function & getFunction()
Return the LLVM function that this machine code represents.
bool isTargetDarwin() const
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
sc_iterator getSuperClasses() const
Returns a NULL-terminated list of super-classes.
bool canRealignStack(const MachineFunction &MF) const override
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
unsigned char getAM5Offset(unsigned AM5Opc)
unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const override
bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override
const TargetRegisterClass *const * sc_iterator
unsigned BasePtr
BasePtr - ARM physical register used as a base ptr in complex stack frames.
ArrayRef< MCPhysReg > getIntraCallClobberedRegs(const MachineFunction *MF) const override
MCSubRegIterator enumerates all sub-registers of Reg.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
@ SwiftTail
SwiftTail - This follows the Swift calling convention in how arguments are passed but guarantees tail...
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
bool supportSwiftError() const override
Return true if the target supports swifterror attribute.
void emitARMRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, ARMCC::CondCodes Pred, Register PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of instructions to materializea des...
virtual const RegClassWeight & getRegClassWeight(const TargetRegisterClass *RC) const =0
Get the weight in units of pressure for this register class.
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...
bool hasBasePointer(const MachineFunction &MF) const
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
void updateRegAllocHint(Register Reg, Register NewReg, MachineFunction &MF) const override
bool isThumb2Function() const
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
virtual void emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred=ARMCC::AL, Register PredReg=Register(), unsigned MIFlags=MachineInstr::NoFlags) const
emitLoadConstPool - Emits a load from constpool to materialize the specified immediate.
std::pair< Register, Register > getRegAllocationHint(Register VReg) const
getRegAllocationHint - Return the register allocation hint for the specified virtual register.
Wrapper class representing physical registers. Should be passed by value.