50#define DEBUG_TYPE "arm-register-info"
52#define GET_REGINFO_TARGET_DESC
53#include "ARMGenRegisterInfo.inc"
72 return CSR_NoRegs_SaveList;
74 return CSR_Win_SplitFP_SaveList;
76 return CSR_Win_AAPCS_CFGuard_Check_SaveList;
80 ? CSR_ATPCS_SplitPush_SwiftTail_SaveList
81 : CSR_AAPCS_SwiftTail_SaveList);
82 }
else if (
F.hasFnAttribute(
"interrupt")) {
87 ? CSR_ATPCS_SplitPush_SaveList
89 }
else if (
F.getFnAttribute(
"interrupt").getValueAsString() ==
"FIQ") {
92 return CSR_FIQ_SaveList;
96 return CSR_GenericInt_SaveList;
101 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError)) {
103 return CSR_iOS_SwiftError_SaveList;
106 ? CSR_ATPCS_SplitPush_SwiftError_SaveList
107 : CSR_AAPCS_SwiftError_SaveList;
112 ? CSR_iOS_CXX_TLS_PE_SaveList
113 : CSR_iOS_CXX_TLS_SaveList;
116 return CSR_iOS_SaveList;
119 return STI.createAAPCSFrameChain() ? CSR_AAPCS_SplitPush_R7_SaveList
120 : CSR_ATPCS_SplitPush_SaveList;
123 return CSR_AAPCS_SplitPush_R11_SaveList;
125 return CSR_AAPCS_SaveList;
130 assert(MF &&
"Invalid MachineFunction pointer.");
133 return CSR_iOS_CXX_TLS_ViaCopy_SaveList;
143 return CSR_NoRegs_RegMask;
145 return CSR_Win_AAPCS_CFGuard_Check_RegMask;
148 : CSR_AAPCS_SwiftTail_RegMask;
153 : CSR_AAPCS_SwiftError_RegMask;
156 return CSR_iOS_CXX_TLS_RegMask;
157 return STI.
isTargetDarwin() ? CSR_iOS_RegMask : CSR_AAPCS_RegMask;
162 return CSR_NoRegs_RegMask;
168 "only know about special TLS call on Darwin");
169 return CSR_iOS_TLSCall_RegMask;
176 return CSR_NoRegs_RegMask;
178 return CSR_FPRegs_RegMask;
197 : CSR_AAPCS_ThisReturn_RegMask;
202 static const MCPhysReg IntraCallClobberedRegs[] = {ARM::R12};
215 markSuperRegs(
Reserved, ARM::FPSCR);
216 markSuperRegs(
Reserved, ARM::APSR_NZCV);
217 if (TFI->isFPReserved(MF))
226 static_assert(ARM::D31 ==
ARM::D16 + 15,
"Register list not consecutive!");
227 for (
unsigned R = 0; R < 16; ++R)
231 for (
unsigned Reg : RC)
248 unsigned PhysReg)
const {
254 if (TFI->isFPReserved(MF))
265 unsigned SuperID = RC->
getID();
270 case ARM::GPRRegClassID:
271 case ARM::SPRRegClassID:
272 case ARM::DPRRegClassID:
273 case ARM::GPRPairRegClassID:
275 case ARM::QPRRegClassID:
276 case ARM::QQPRRegClassID:
277 case ARM::QQQQPRRegClassID:
281 case ARM::MQPRRegClassID:
282 case ARM::MQQPRRegClassID:
283 case ARM::MQQQQPRRegClassID:
288 SuperID = (
I != E) ? *
I++ : ~0U;
289 }
while (SuperID != ~0U);
296 return &ARM::GPRRegClass;
301 if (RC == &ARM::CCRRegClass)
302 return &ARM::rGPRRegClass;
303 if (RC == &ARM::cl_FPSCR_NZCVRegClass)
304 return &ARM::rGPRRegClass;
314 switch (RC->
getID()) {
317 case ARM::tGPRRegClassID: {
322 ? TFI->hasFP(MF) :
true;
325 case ARM::GPRRegClassID: {
327 ? TFI->hasFP(MF) :
true;
330 case ARM::SPRRegClassID:
331 case ARM::DPRRegClassID:
340 if (ARM::GPRPairRegClass.
contains(Super))
341 return RI->
getSubReg(Super, Odd ? ARM::gsub_1 : ARM::gsub_0);
351 std::pair<unsigned, Register> Hint =
MRI.getRegAllocationHint(VirtReg);
354 switch (Hint.first) {
363 if (
MRI.getRegClass(VirtReg)->contains(ARM::LR))
380 }
else if (VRM && VRM->
hasPhys(Paired)) {
390 if (Reg == PairedPhys || (getEncodingValue(Reg) & 1) != Odd)
394 if (!Paired ||
MRI.isReserved(Paired))
404 std::pair<unsigned, Register> Hint =
MRI->getRegAllocationHint(Reg);
406 Hint.second.isVirtual()) {
412 Hint =
MRI->getRegAllocationHint(OtherReg);
414 if (Hint.second == Reg) {
415 MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg);
417 MRI->setRegAllocationHint(NewReg,
434 if (hasStackRealignment(MF) && !TFI->hasReservedCallFrame(MF))
491 hasStackRealignment(MF);
544 int64_t InstrOffs = 0;
553 InstrOffs =
MI->getOperand(
Idx+1).getImm();
561 InstrOffs = -InstrOffs;
569 InstrOffs = -InstrOffs;
575 InstrOffs = -InstrOffs;
579 InstrOffs =
MI->getOperand(ImmIdx).getImm();
586 return InstrOffs * Scale;
595 for (
unsigned i = 0; !
MI->getOperand(i).isFI(); ++i) {
596 assert(i < MI->getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
608 unsigned Opc =
MI->getOpcode();
610 case ARM::LDRi12:
case ARM::LDRH:
case ARM::LDRBi12:
611 case ARM::STRi12:
case ARM::STRH:
case ARM::STRBi12:
612 case ARM::t2LDRi12:
case ARM::t2LDRi8:
613 case ARM::t2STRi12:
case ARM::t2STRi8:
614 case ARM::VLDRS:
case ARM::VLDRD:
615 case ARM::VSTRS:
case ARM::VSTRD:
616 case ARM::tSTRspi:
case ARM::tLDRspi:
636 int64_t FPOffset =
Offset - 8;
654 if (TFI->
hasFP(MF) &&
685 DL = Ins->getDebugLoc();
691 Register BaseReg =
MRI.createVirtualRegister(&ARM::GPRRegClass);
692 MRI.constrainRegClass(BaseReg,
TII.getRegClass(MCID, 0,
this, MF));
714 "This resolveFrameIndex does not support Thumb1!");
716 while (!
MI.getOperand(i).isFI()) {
718 assert(i <
MI.getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
727 assert(
Done &&
"Unable to resolve frame index!");
737 for (; !
MI->getOperand(i).isFI(); ++i)
738 assert(i+1 <
MI->getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
744 unsigned NumBits = 0;
775 NumBits = (BaseReg == ARM::SP ? 8 : 5);
786 if ((
Offset & (Scale-1)) != 0)
792 unsigned Mask = (1 << NumBits) - 1;
793 if ((
unsigned)
Offset <= Mask * Scale)
801 int SPAdj,
unsigned FIOperandNum,
811 "This eliminateFrameIndex does not support Thumb1!");
812 int FrameIndex =
MI.getOperand(FIOperandNum).getIndex();
824 "Cannot use SP to access the emergency spill slot in "
825 "functions without a reserved call frame");
827 "Cannot use SP to access the emergency spill slot in "
828 "functions with variable sized frame objects");
832 assert(!
MI.isDebugValue() &&
"DBG_VALUEs should be handled in target-independent code");
856 "This code isn't needed if offset already handled!");
858 unsigned ScratchReg = 0;
859 int PIdx =
MI.findFirstPredOperandIdx();
866 TII.getRegClass(MCID, FIOperandNum,
this, *
MI.getParent()->getParent());
870 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg,
false,
false,
false);
882 MI.getOperand(FIOperandNum).ChangeToRegister(ScratchReg,
false,
false,
true);
894 auto MBB =
MI->getParent();
902 if (getRegSizeInBits(*NewRC) < 256 && getRegSizeInBits(*DstRC) < 256 &&
903 getRegSizeInBits(*SrcRC) < 256)
907 MRI.getTargetRegisterInfo()->getRegClassWeight(NewRC);
909 MRI.getTargetRegisterInfo()->getRegClassWeight(SrcRC);
911 MRI.getTargetRegisterInfo()->getRegClassWeight(DstRC);
914 if (SrcRCWeight.RegWeight > NewRCWeight.RegWeight)
916 if (DstRCWeight.RegWeight > NewRCWeight.RegWeight)
927 << It->second <<
"\n");
929 << NewRCWeight.RegWeight <<
"\n");
937 unsigned SizeMultiplier =
MBB->
size()/100;
938 SizeMultiplier = SizeMultiplier ? SizeMultiplier : 1;
939 if (It->second < NewRCWeight.WeightLimit * SizeMultiplier) {
940 It->second += NewRCWeight.RegWeight;
949 unsigned SrcSubReg)
const {
951 if (DefRC == &ARM::SPRRegClass && DefSubReg == 0 &&
952 SrcRC == &ARM::DPRRegClass &&
953 (SrcSubReg == ARM::ssub_0 || SrcSubReg == ARM::ssub_1))
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
static MCPhysReg getPairedGPR(MCPhysReg Reg, bool Odd, const MCRegisterInfo *RI)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file contains the simple types necessary to represent the attributes associated with functions a...
This file implements the BitVector class.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static bool isSigned(unsigned int Opcode)
const HexagonInstrInfo * TII
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
uint64_t IntrinsicInst * II
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
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 hasBasePointer(const MachineFunction &MF) const
bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, int64_t Offset) const override
BitVector getReservedRegs(const MachineFunction &MF) const override
int64_t getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const override
void updateRegAllocHint(Register Reg, Register NewReg, MachineFunction &MF) const override
const uint32_t * getNoPreservedMask() const override
bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, unsigned DefSubReg, const TargetRegisterClass *SrcRC, unsigned SrcSubReg) const override
bool requiresVirtualBaseRegisters(const MachineFunction &MF) 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.
const uint32_t * getSjLjDispatchPreservedMask(const MachineFunction &MF) const
bool eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const override
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &MF) const override
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
bool cannotEliminateFrame(const MachineFunction &MF) const
Register getFrameRegister(const MachineFunction &MF) const override
bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const override
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, int64_t Offset) const override
materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to be a pointer to FrameIdx...
bool requiresRegisterScavenging(const MachineFunction &MF) const override
Code Generation virtual methods...
const uint32_t * getTLSCallPreservedMask(const MachineFunction &MF) const
void resolveFrameIndex(MachineInstr &MI, Register BaseReg, int64_t Offset) const override
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override
unsigned BasePtr
BasePtr - ARM physical register used as a base ptr in complex stack frames.
bool isInlineAsmReadOnlyReg(const MachineFunction &MF, unsigned PhysReg) const override
ArrayRef< MCPhysReg > getIntraCallClobberedRegs(const MachineFunction *MF) const override
const TargetRegisterClass * getCrossCopyRegClass(const TargetRegisterClass *RC) const override
const MCPhysReg * getCalleeSavedRegsViaCopy(const MachineFunction *MF) const
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override
needsFrameBaseReg - Returns true if the instruction's frame index reference would be better served by...
const uint32_t * getThisReturnPreservedMask(const MachineFunction &MF, CallingConv::ID) const
getThisReturnPreservedMask - Returns a call preserved mask specific to the case that 'returned' is on...
bool canRealignStack(const MachineFunction &MF) const override
unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const override
bool requiresFrameIndexScavenging(const MachineFunction &MF) const override
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
int ResolveFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg, int SPAdj) const
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
bool isThumb2Function() const
bool isThumb1OnlyFunction() const
bool isThumbFunction() const
DenseMap< constMachineBasicBlock *, unsigned >::iterator getCoalescedWeight(MachineBasicBlock *MBB)
bool isThumb1Only() const
MCPhysReg getFramePointerReg() const
const ARMTargetLowering * getTargetLowering() const override
bool isTargetDarwin() const
bool isR9Reserved() const
enum PushPopSplitVariation getPushPopSplitVariation(const MachineFunction &MF) const
PushPopSplitVariation
How the push and pop instructions of callee saved general-purpose registers should be split.
@ SplitR11WindowsSEH
When the stack frame size is not known (because of variable-sized objects or realignment),...
@ SplitR7
R7 and LR must be adjacent, because R7 is the frame pointer, and must point to a frame record consist...
@ SplitR11AAPCSSignRA
When generating AAPCS-compilant frame chains, R11 is the frame pointer, and must be pushed adjacent t...
bool supportSwiftError() const override
Return true if the target supports swifterror attribute.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
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 test(unsigned Idx) const
This is an important base class in LLVM.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Describe properties that are true of each instruction in the target description file.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
iterator_range< MCSuperRegIterator > superregs(MCRegister Reg) const
Return an iterator range over all super-registers of Reg, excluding Reg.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
Align getLocalFrameMaxAlign() const
Return the required alignment of the local object blob.
bool isMaxCallFrameSizeComputed() const
int64_t getLocalFrameSize() const
Get the size of the local object blob.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool isScavengingFrameIndex(int FI) const
Query whether a frame index is a scavenging frame index.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
unsigned getID() const
Return the register class ID number.
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
ArrayRef< unsigned > superclasses() const
Returns a list of super-classes.
virtual bool canRealignStack(const MachineFunction &MF) const
True if the stack can be realigned for the target.
virtual bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, unsigned DefSubReg, const TargetRegisterClass *SrcRC, unsigned SrcSubReg) const
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...
virtual const TargetInstrInfo * getInstrInfo() const
static IntegerType * getInt32Ty(LLVMContext &C)
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
bool hasPhys(Register virtReg) const
returns true if the specified virtual register is mapped to a physical register
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned char getAM3Offset(unsigned AM3Opc)
unsigned getAM2Offset(unsigned AM2Opc)
AddrOpc getAM5Op(unsigned AM5Opc)
unsigned char getAM5Offset(unsigned AM5Opc)
AddrOpc getAM2Op(unsigned AM2Opc)
AddrOpc getAM3Op(unsigned AM3Opc)
void initLLVMToCVRegMapping(MCRegisterInfo *MRI)
@ D16
Only 16 D registers.
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
@ CXX_FAST_TLS
Used for access functions.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, Register FrameReg, int &Offset, const ARMBaseInstrInfo &TII, const TargetRegisterInfo *TRI)
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getDefRegState(bool B)
bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, Register FrameReg, int &Offset, const ARMBaseInstrInfo &TII)
rewriteARMFrameIndex / rewriteT2FrameIndex - Rewrite MI to access 'Offset' bytes from the FP.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
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...
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)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Description of the encoding of one expression Op.