Changeset View
Changeset View
Standalone View
Standalone View
lib/Target/ARM/ARMBaseRegisterInfo.cpp
Show First 20 Lines • Show All 183 Lines • ▼ Show 20 Lines | getReservedRegs(const MachineFunction &MF) const { | ||||
markSuperRegs(Reserved, ARM::SP); | markSuperRegs(Reserved, ARM::SP); | ||||
markSuperRegs(Reserved, ARM::PC); | markSuperRegs(Reserved, ARM::PC); | ||||
markSuperRegs(Reserved, ARM::FPSCR); | markSuperRegs(Reserved, ARM::FPSCR); | ||||
markSuperRegs(Reserved, ARM::APSR_NZCV); | markSuperRegs(Reserved, ARM::APSR_NZCV); | ||||
if (TFI->hasFP(MF)) | if (TFI->hasFP(MF)) | ||||
markSuperRegs(Reserved, getFramePointerReg(STI)); | markSuperRegs(Reserved, getFramePointerReg(STI)); | ||||
if (hasBasePointer(MF)) | if (hasBasePointer(MF)) | ||||
markSuperRegs(Reserved, BasePtr); | markSuperRegs(Reserved, BasePtr); | ||||
// Some targets reserve R9. | for (size_t R = 0; R < ARM::GPRRegClass.getNumRegs(); ++R) { | ||||
if (STI.isR9Reserved()) | if (STI.isRRegisterReserved(R)) { | ||||
markSuperRegs(Reserved, ARM::R9); | markSuperRegs(Reserved, ARM::R0 + R); | ||||
} | |||||
} | |||||
// Reserve D16-D31 if the subtarget doesn't support them. | // Reserve D16-D31 if the subtarget doesn't support them. | ||||
if (!STI.hasVFP3() || STI.hasD16()) { | if (!STI.hasVFP3() || STI.hasD16()) { | ||||
static_assert(ARM::D31 == ARM::D16 + 15, "Register list not consecutive!"); | static_assert(ARM::D31 == ARM::D16 + 15, "Register list not consecutive!"); | ||||
for (unsigned R = 0; R < 16; ++R) | for (unsigned R = 0; R < 16; ++R) | ||||
markSuperRegs(Reserved, ARM::D16 + R); | markSuperRegs(Reserved, ARM::D16 + R); | ||||
} | } | ||||
const TargetRegisterClass &RC = ARM::GPRPairRegClass; | const TargetRegisterClass &RC = ARM::GPRPairRegClass; | ||||
for (unsigned Reg : RC) | for (unsigned Reg : RC) | ||||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | case ARM::tGPRRegClassID: { | ||||
// ScheduleDAGRRList. | // ScheduleDAGRRList. | ||||
bool HasFP = MF.getFrameInfo().isMaxCallFrameSizeComputed() | bool HasFP = MF.getFrameInfo().isMaxCallFrameSizeComputed() | ||||
? TFI->hasFP(MF) : true; | ? TFI->hasFP(MF) : true; | ||||
return 5 - HasFP; | return 5 - HasFP; | ||||
} | } | ||||
case ARM::GPRRegClassID: { | case ARM::GPRRegClassID: { | ||||
bool HasFP = MF.getFrameInfo().isMaxCallFrameSizeComputed() | bool HasFP = MF.getFrameInfo().isMaxCallFrameSizeComputed() | ||||
? TFI->hasFP(MF) : true; | ? TFI->hasFP(MF) : true; | ||||
return 10 - HasFP - (STI.isR9Reserved() ? 1 : 0); | return 10 - HasFP - STI.getNumRRegisterReserved(); | ||||
} | } | ||||
case ARM::SPRRegClassID: // Currently not used as 'rep' register class. | case ARM::SPRRegClassID: // Currently not used as 'rep' register class. | ||||
case ARM::DPRRegClassID: | case ARM::DPRRegClassID: | ||||
return 32 - 10; | return 32 - 10; | ||||
} | } | ||||
} | } | ||||
// Get the other register in a GPRPair. | // Get the other register in a GPRPair. | ||||
▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | if ((Hint.first == (unsigned)ARMRI::RegPairOdd || | ||||
} | } | ||||
} | } | ||||
} | } | ||||
bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const { | bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const { | ||||
const MachineFrameInfo &MFI = MF.getFrameInfo(); | const MachineFrameInfo &MFI = MF.getFrameInfo(); | ||||
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | ||||
const ARMFrameLowering *TFI = getFrameLowering(MF); | const ARMFrameLowering *TFI = getFrameLowering(MF); | ||||
const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); | |||||
// Disable base pointer R6 if -ffixed-r6 is used. | |||||
if (STI.isRRegisterReserved(BasePtr-ARM::R0)) | |||||
return false; | |||||
efriedma: In the case where we have stack realignment and VLAs, what happens? IIRC we don't have any… | |||||
// When outgoing call frames are so large that we adjust the stack pointer | // When outgoing call frames are so large that we adjust the stack pointer | ||||
// around the call, we can no longer use the stack pointer to reach the | // around the call, we can no longer use the stack pointer to reach the | ||||
// emergency spill slot. | // emergency spill slot. | ||||
if (needsStackRealignment(MF) && !TFI->hasReservedCallFrame(MF)) | if (needsStackRealignment(MF) && !TFI->hasReservedCallFrame(MF)) | ||||
return true; | return true; | ||||
// Thumb has trouble with negative offsets from the FP. Thumb2 has a limited | // Thumb has trouble with negative offsets from the FP. Thumb2 has a limited | ||||
Show All 14 Lines | bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const { | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const { | bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const { | ||||
const MachineRegisterInfo *MRI = &MF.getRegInfo(); | const MachineRegisterInfo *MRI = &MF.getRegInfo(); | ||||
const ARMFrameLowering *TFI = getFrameLowering(MF); | const ARMFrameLowering *TFI = getFrameLowering(MF); | ||||
const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); | |||||
// We can't realign the stack if: | // We can't realign the stack if: | ||||
// 1. Dynamic stack realignment is explicitly disabled, | // 1. Dynamic stack realignment is explicitly disabled, | ||||
// 2. There are VLAs in the function and the base pointer is disabled. | // 2. There are VLAs in the function and the base pointer is disabled. | ||||
if (!TargetRegisterInfo::canRealignStack(MF)) | if (!TargetRegisterInfo::canRealignStack(MF)) | ||||
return false; | return false; | ||||
// Stack realignment requires a frame pointer. If we already started | // Stack realignment requires a frame pointer. If we already started | ||||
// register allocation with frame pointer elimination, it is too late now. | // register allocation with frame pointer elimination, it is too late now. | ||||
if (!MRI->canReserveReg(getFramePointerReg(MF.getSubtarget<ARMSubtarget>()))) | if (!MRI->canReserveReg(getFramePointerReg(MF.getSubtarget<ARMSubtarget>()))) | ||||
return false; | return false; | ||||
// Disable base pointer R6 if -ffixed-r6 is used. | |||||
if (STI.isRRegisterReserved(BasePtr-ARM::R0)) | |||||
return false; | |||||
// We may also need a base pointer if there are dynamic allocas or stack | // We may also need a base pointer if there are dynamic allocas or stack | ||||
// pointer adjustments around calls. | // pointer adjustments around calls. | ||||
if (TFI->hasReservedCallFrame(MF)) | if (TFI->hasReservedCallFrame(MF)) | ||||
return true; | return true; | ||||
// A base pointer is required and allowed. Check that it isn't too late to | // A base pointer is required and allowed. Check that it isn't too late to | ||||
// reserve it. | // reserve it. | ||||
return MRI->canReserveReg(BasePtr); | return MRI->canReserveReg(BasePtr); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 447 Lines • Show Last 20 Lines |
In the case where we have stack realignment and VLAs, what happens? IIRC we don't have any code to generate an alternate sequence (although I guess that would be theoretically possible to dynamically allocate stack slots that would otherwise require realignment). Do we print an error message?