Changeset View
Changeset View
Standalone View
Standalone View
llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp
Show First 20 Lines • Show All 439 Lines • ▼ Show 20 Lines | static bool MustSaveLR(const MachineFunction &MF, unsigned LR) { | ||||
// We need a save/restore of LR if there is any def of LR (which is | // We need a save/restore of LR if there is any def of LR (which is | ||||
// defined by calls, including the PIC setup sequence), or if there is | // defined by calls, including the PIC setup sequence), or if there is | ||||
// some use of the LR stack slot (e.g. for builtin_return_address). | // some use of the LR stack slot (e.g. for builtin_return_address). | ||||
// (LR comes in 32 and 64 bit versions.) | // (LR comes in 32 and 64 bit versions.) | ||||
MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR); | MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR); | ||||
return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired(); | return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired(); | ||||
} | } | ||||
/// determineFrameLayoutAndUpdate - Determine the size of the frame and maximum | |||||
/// call frame size. Update the MachineFunction object with the stack size. | |||||
unsigned | |||||
PPCFrameLowering::determineFrameLayoutAndUpdate(MachineFunction &MF, | |||||
bool UseEstimate) const { | |||||
unsigned NewMaxCallFrameSize = 0; | |||||
unsigned FrameSize = determineFrameLayout(MF, UseEstimate, | |||||
&NewMaxCallFrameSize); | |||||
MF.getFrameInfo().setStackSize(FrameSize); | |||||
MF.getFrameInfo().setMaxCallFrameSize(NewMaxCallFrameSize); | |||||
return FrameSize; | |||||
} | |||||
/// determineFrameLayout - Determine the size of the frame and maximum call | /// determineFrameLayout - Determine the size of the frame and maximum call | ||||
/// frame size. | /// frame size. | ||||
unsigned PPCFrameLowering::determineFrameLayout(MachineFunction &MF, | unsigned | ||||
bool UpdateMF, | PPCFrameLowering::determineFrameLayout(const MachineFunction &MF, | ||||
bool UseEstimate) const { | bool UseEstimate, | ||||
MachineFrameInfo &MFI = MF.getFrameInfo(); | unsigned *NewMaxCallFrameSize) const { | ||||
const MachineFrameInfo &MFI = MF.getFrameInfo(); | |||||
// Get the number of bytes to allocate from the FrameInfo | // Get the number of bytes to allocate from the FrameInfo | ||||
unsigned FrameSize = | unsigned FrameSize = | ||||
UseEstimate ? MFI.estimateStackSize(MF) : MFI.getStackSize(); | UseEstimate ? MFI.estimateStackSize(MF) : MFI.getStackSize(); | ||||
// Get stack alignments. The frame must be aligned to the greatest of these: | // Get stack alignments. The frame must be aligned to the greatest of these: | ||||
unsigned TargetAlign = getStackAlignment(); // alignment required per the ABI | unsigned TargetAlign = getStackAlignment(); // alignment required per the ABI | ||||
unsigned MaxAlign = MFI.getMaxAlignment(); // algmt required by data in frame | unsigned MaxAlign = MFI.getMaxAlignment(); // algmt required by data in frame | ||||
Show All 9 Lines | bool CanUseRedZone = !MFI.hasVarSizedObjects() && // No dynamic alloca. | ||||
!RegInfo->hasBasePointer(MF); // No special alignment. | !RegInfo->hasBasePointer(MF); // No special alignment. | ||||
// Note: for PPC32 SVR4ABI (Non-DarwinABI), we can still generate stackless | // Note: for PPC32 SVR4ABI (Non-DarwinABI), we can still generate stackless | ||||
// code if all local vars are reg-allocated. | // code if all local vars are reg-allocated. | ||||
bool FitsInRedZone = FrameSize <= Subtarget.getRedZoneSize(); | bool FitsInRedZone = FrameSize <= Subtarget.getRedZoneSize(); | ||||
// Check whether we can skip adjusting the stack pointer (by using red zone) | // Check whether we can skip adjusting the stack pointer (by using red zone) | ||||
if (!DisableRedZone && CanUseRedZone && FitsInRedZone) { | if (!DisableRedZone && CanUseRedZone && FitsInRedZone) { | ||||
NumNoNeedForFrame++; | |||||
// No need for frame | // No need for frame | ||||
if (UpdateMF) | |||||
MFI.setStackSize(0); | |||||
return 0; | return 0; | ||||
} | } | ||||
// Get the maximum call frame size of all the calls. | // Get the maximum call frame size of all the calls. | ||||
unsigned maxCallFrameSize = MFI.getMaxCallFrameSize(); | unsigned maxCallFrameSize = MFI.getMaxCallFrameSize(); | ||||
// Maximum call frame needs to be at least big enough for linkage area. | // Maximum call frame needs to be at least big enough for linkage area. | ||||
unsigned minCallFrameSize = getLinkageSize(); | unsigned minCallFrameSize = getLinkageSize(); | ||||
maxCallFrameSize = std::max(maxCallFrameSize, minCallFrameSize); | maxCallFrameSize = std::max(maxCallFrameSize, minCallFrameSize); | ||||
// If we have dynamic alloca then maxCallFrameSize needs to be aligned so | // If we have dynamic alloca then maxCallFrameSize needs to be aligned so | ||||
// that allocations will be aligned. | // that allocations will be aligned. | ||||
if (MFI.hasVarSizedObjects()) | if (MFI.hasVarSizedObjects()) | ||||
maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask; | maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask; | ||||
// Update maximum call frame size. | // Update the new max call frame size if the caller passes in a valid pointer. | ||||
if (UpdateMF) | if (NewMaxCallFrameSize) | ||||
MFI.setMaxCallFrameSize(maxCallFrameSize); | *NewMaxCallFrameSize = maxCallFrameSize; | ||||
// Include call frame size in total. | // Include call frame size in total. | ||||
FrameSize += maxCallFrameSize; | FrameSize += maxCallFrameSize; | ||||
// Make sure the frame is aligned. | // Make sure the frame is aligned. | ||||
FrameSize = (FrameSize + AlignMask) & ~AlignMask; | FrameSize = (FrameSize + AlignMask) & ~AlignMask; | ||||
// Update frame info. | |||||
if (UpdateMF) | |||||
MFI.setStackSize(FrameSize); | |||||
return FrameSize; | return FrameSize; | ||||
} | } | ||||
// hasFP - Return true if the specified function actually has a dedicated frame | // hasFP - Return true if the specified function actually has a dedicated frame | ||||
// pointer register. | // pointer register. | ||||
bool PPCFrameLowering::hasFP(const MachineFunction &MF) const { | bool PPCFrameLowering::hasFP(const MachineFunction &MF) const { | ||||
const MachineFrameInfo &MFI = MF.getFrameInfo(); | const MachineFrameInfo &MFI = MF.getFrameInfo(); | ||||
// FIXME: This is pretty much broken by design: hasFP() might be called really | // FIXME: This is pretty much broken by design: hasFP() might be called really | ||||
▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | |||||
// register is available, we can adjust for that by not overlapping the spill | // register is available, we can adjust for that by not overlapping the spill | ||||
// code. However, if we need to realign the stack (i.e. have a base pointer) | // code. However, if we need to realign the stack (i.e. have a base pointer) | ||||
// and the stack frame is large, we need two scratch registers. | // and the stack frame is large, we need two scratch registers. | ||||
bool | bool | ||||
PPCFrameLowering::twoUniqueScratchRegsRequired(MachineBasicBlock *MBB) const { | PPCFrameLowering::twoUniqueScratchRegsRequired(MachineBasicBlock *MBB) const { | ||||
const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo(); | const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo(); | ||||
MachineFunction &MF = *(MBB->getParent()); | MachineFunction &MF = *(MBB->getParent()); | ||||
bool HasBP = RegInfo->hasBasePointer(MF); | bool HasBP = RegInfo->hasBasePointer(MF); | ||||
unsigned FrameSize = determineFrameLayout(MF, false); | unsigned FrameSize = determineFrameLayout(MF); | ||||
int NegFrameSize = -FrameSize; | int NegFrameSize = -FrameSize; | ||||
bool IsLargeFrame = !isInt<16>(NegFrameSize); | bool IsLargeFrame = !isInt<16>(NegFrameSize); | ||||
MachineFrameInfo &MFI = MF.getFrameInfo(); | MachineFrameInfo &MFI = MF.getFrameInfo(); | ||||
unsigned MaxAlign = MFI.getMaxAlignment(); | unsigned MaxAlign = MFI.getMaxAlignment(); | ||||
bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI(); | bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI(); | ||||
return (IsLargeFrame || !HasRedZone) && HasBP && MaxAlign > 1; | return (IsLargeFrame || !HasRedZone) && HasBP && MaxAlign > 1; | ||||
} | } | ||||
bool PPCFrameLowering::canUseAsPrologue(const MachineBasicBlock &MBB) const { | bool PPCFrameLowering::canUseAsPrologue(const MachineBasicBlock &MBB) const { | ||||
MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB); | MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB); | ||||
return findScratchRegister(TmpMBB, false, | return findScratchRegister(TmpMBB, false, | ||||
twoUniqueScratchRegsRequired(TmpMBB)); | twoUniqueScratchRegsRequired(TmpMBB)); | ||||
} | } | ||||
bool PPCFrameLowering::canUseAsEpilogue(const MachineBasicBlock &MBB) const { | bool PPCFrameLowering::canUseAsEpilogue(const MachineBasicBlock &MBB) const { | ||||
MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB); | MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB); | ||||
return findScratchRegister(TmpMBB, true); | return findScratchRegister(TmpMBB, true); | ||||
} | } | ||||
bool PPCFrameLowering::stackUpdateCanBeMoved(MachineFunction &MF) const { | |||||
const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo(); | |||||
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); | |||||
// Abort if there is no register info or function info. | |||||
if (!RegInfo || !FI) | |||||
return false; | |||||
// Only move the stack update on ELFv2 ABI and PPC64. | |||||
if (!Subtarget.isELFv2ABI() || !Subtarget.isPPC64()) | |||||
return false; | |||||
// Check the frame size first and return false if it does not fit the | |||||
// requirements. | |||||
// We need a non-zero frame size as well as a frame that will fit in the red | |||||
// zone. This is because by moving the stack pointer update we are now storing | |||||
// to the red zone until the stack pointer is updated. If we get an interrupt | |||||
// inside the prologue but before the stack update we now have a number of | |||||
// stores to the red zone and those stores must all fit. | |||||
MachineFrameInfo &MFI = MF.getFrameInfo(); | |||||
unsigned FrameSize = MFI.getStackSize(); | |||||
if (!FrameSize || FrameSize > Subtarget.getRedZoneSize()) | |||||
return false; | |||||
// Frame pointers and base pointers complicate matters so don't do anything | |||||
// if we have them. For example having a frame pointer will sometimes require | |||||
// a copy of r1 into r31 and that makes keeping track of updates to r1 more | |||||
// difficult. | |||||
if (hasFP(MF) || RegInfo->hasBasePointer(MF)) | |||||
return false; | |||||
// Calls to fast_cc functions use different rules for passing parameters on | |||||
// the stack from the ABI and using PIC base in the function imposes | |||||
// similar restrictions to using the base pointer. It is not generally safe | |||||
// to move the stack pointer update in these situations. | |||||
if (FI->hasFastCall() || FI->usesPICBase()) | |||||
return false; | |||||
// Finally we can move the stack update if we do not require regiser | |||||
// scavenging. Register scavenging can introduce more spills and so | |||||
// may make the frame size larger than we have computed. | |||||
return !RegInfo->requiresFrameIndexScavenging(MF); | |||||
} | |||||
void PPCFrameLowering::emitPrologue(MachineFunction &MF, | void PPCFrameLowering::emitPrologue(MachineFunction &MF, | ||||
MachineBasicBlock &MBB) const { | MachineBasicBlock &MBB) const { | ||||
MachineBasicBlock::iterator MBBI = MBB.begin(); | MachineBasicBlock::iterator MBBI = MBB.begin(); | ||||
MachineFrameInfo &MFI = MF.getFrameInfo(); | MachineFrameInfo &MFI = MF.getFrameInfo(); | ||||
const PPCInstrInfo &TII = *Subtarget.getInstrInfo(); | const PPCInstrInfo &TII = *Subtarget.getInstrInfo(); | ||||
const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo(); | const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo(); | ||||
MachineModuleInfo &MMI = MF.getMMI(); | MachineModuleInfo &MMI = MF.getMMI(); | ||||
Show All 19 Lines | for (unsigned i = 0; MBBI != MBB.end(); ++i, ++MBBI) { | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
// Move MBBI back to the beginning of the prologue block. | // Move MBBI back to the beginning of the prologue block. | ||||
MBBI = MBB.begin(); | MBBI = MBB.begin(); | ||||
// Work out frame sizes. | // Work out frame sizes. | ||||
unsigned FrameSize = determineFrameLayout(MF); | unsigned FrameSize = determineFrameLayoutAndUpdate(MF); | ||||
int NegFrameSize = -FrameSize; | int NegFrameSize = -FrameSize; | ||||
if (!isInt<32>(NegFrameSize)) | if (!isInt<32>(NegFrameSize)) | ||||
llvm_unreachable("Unhandled stack size!"); | llvm_unreachable("Unhandled stack size!"); | ||||
if (MFI.isFrameAddressTaken()) | if (MFI.isFrameAddressTaken()) | ||||
replaceFPWithRealFP(MF); | replaceFPWithRealFP(MF); | ||||
// Check if the link register (LR) must be saved. | // Check if the link register (LR) must be saved. | ||||
▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | void PPCFrameLowering::emitPrologue(MachineFunction &MF, | ||||
// Frames of 32KB & larger require special handling because they cannot be | // Frames of 32KB & larger require special handling because they cannot be | ||||
// indexed into with a simple STDU/STWU/STD/STW immediate offset operand. | // indexed into with a simple STDU/STWU/STD/STW immediate offset operand. | ||||
bool isLargeFrame = !isInt<16>(NegFrameSize); | bool isLargeFrame = !isInt<16>(NegFrameSize); | ||||
assert((isPPC64 || !MustSaveCR) && | assert((isPPC64 || !MustSaveCR) && | ||||
"Prologue CR saving supported only in 64-bit mode"); | "Prologue CR saving supported only in 64-bit mode"); | ||||
// Check if we can move the stack update instruction (stdu) down the prologue | |||||
// past the callee saves. Hopefully this will avoid the situation where the | |||||
// saves are waiting for the update on the store with update to complete. | |||||
MachineBasicBlock::iterator StackUpdateLoc = MBBI; | |||||
bool MovingStackUpdateDown = false; | |||||
// Check if we can move the stack update. | |||||
if (stackUpdateCanBeMoved(MF)) { | |||||
const std::vector<CalleeSavedInfo> &Info = MFI.getCalleeSavedInfo(); | |||||
for (CalleeSavedInfo CSI : Info) { | |||||
int FrIdx = CSI.getFrameIdx(); | |||||
// If the frame index is not negative the callee saved info belongs to a | |||||
// stack object that is not a fixed stack object. We ignore non-fixed | |||||
// stack objects because we won't move the stack update pointer past them. | |||||
if (FrIdx >= 0) | |||||
continue; | |||||
if (MFI.isFixedObjectIndex(FrIdx) && MFI.getObjectOffset(FrIdx) < 0) { | |||||
StackUpdateLoc++; | |||||
MovingStackUpdateDown = true; | |||||
} else { | |||||
// We need all of the Frame Indices to meet these conditions. | |||||
// If they do not, abort the whole operation. | |||||
StackUpdateLoc = MBBI; | |||||
MovingStackUpdateDown = false; | |||||
break; | |||||
} | |||||
} | |||||
// If the operation was not aborted then update the object offset. | |||||
if (MovingStackUpdateDown) { | |||||
for (CalleeSavedInfo CSI : Info) { | |||||
int FrIdx = CSI.getFrameIdx(); | |||||
if (FrIdx < 0) | |||||
MFI.setObjectOffset(FrIdx, MFI.getObjectOffset(FrIdx) + NegFrameSize); | |||||
} | |||||
} | |||||
} | |||||
// If we need to spill the CR and the LR but we don't have two separate | // If we need to spill the CR and the LR but we don't have two separate | ||||
// registers available, we must spill them one at a time | // registers available, we must spill them one at a time | ||||
if (MustSaveCR && SingleScratchReg && MustSaveLR) { | if (MustSaveCR && SingleScratchReg && MustSaveLR) { | ||||
// In the ELFv2 ABI, we are not required to save all CR fields. | // In the ELFv2 ABI, we are not required to save all CR fields. | ||||
// If only one or two CR fields are clobbered, it is more efficient to use | // If only one or two CR fields are clobbered, it is more efficient to use | ||||
// mfocrf to selectively save just those fields, because mfocrf has short | // mfocrf to selectively save just those fields, because mfocrf has short | ||||
// latency compares to mfcr. | // latency compares to mfcr. | ||||
unsigned MfcrOpcode = PPC::MFCR8; | unsigned MfcrOpcode = PPC::MFCR8; | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | if (HasRedZone) { | ||||
if (HasBP) | if (HasBP) | ||||
BuildMI(MBB, MBBI, dl, StoreInst) | BuildMI(MBB, MBBI, dl, StoreInst) | ||||
.addReg(BPReg) | .addReg(BPReg) | ||||
.addImm(BPOffset) | .addImm(BPOffset) | ||||
.addReg(SPReg); | .addReg(SPReg); | ||||
} | } | ||||
if (MustSaveLR) | if (MustSaveLR) | ||||
BuildMI(MBB, MBBI, dl, StoreInst) | BuildMI(MBB, StackUpdateLoc, dl, StoreInst) | ||||
.addReg(ScratchReg, getKillRegState(true)) | .addReg(ScratchReg, getKillRegState(true)) | ||||
.addImm(LROffset) | .addImm(LROffset) | ||||
.addReg(SPReg); | .addReg(SPReg); | ||||
if (MustSaveCR && | if (MustSaveCR && | ||||
!(SingleScratchReg && MustSaveLR)) { // will only occur for PPC64 | !(SingleScratchReg && MustSaveLR)) { // will only occur for PPC64 | ||||
assert(HasRedZone && "A red zone is always available on PPC64"); | assert(HasRedZone && "A red zone is always available on PPC64"); | ||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::STW8)) | BuildMI(MBB, MBBI, dl, TII.get(PPC::STW8)) | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | if (HasBP && MaxAlign > 1) { | ||||
BuildMI(MBB, MBBI, dl, StoreUpdtIdxInst, SPReg) | BuildMI(MBB, MBBI, dl, StoreUpdtIdxInst, SPReg) | ||||
.addReg(SPReg, RegState::Kill) | .addReg(SPReg, RegState::Kill) | ||||
.addReg(SPReg) | .addReg(SPReg) | ||||
.addReg(ScratchReg); | .addReg(ScratchReg); | ||||
HasSTUX = true; | HasSTUX = true; | ||||
} else if (!isLargeFrame) { | } else if (!isLargeFrame) { | ||||
BuildMI(MBB, MBBI, dl, StoreUpdtInst, SPReg) | BuildMI(MBB, StackUpdateLoc, dl, StoreUpdtInst, SPReg) | ||||
.addReg(SPReg) | .addReg(SPReg) | ||||
.addImm(NegFrameSize) | .addImm(NegFrameSize) | ||||
.addReg(SPReg); | .addReg(SPReg); | ||||
} else { | } else { | ||||
BuildMI(MBB, MBBI, dl, LoadImmShiftedInst, ScratchReg) | BuildMI(MBB, MBBI, dl, LoadImmShiftedInst, ScratchReg) | ||||
.addImm(NegFrameSize >> 16); | .addImm(NegFrameSize >> 16); | ||||
BuildMI(MBB, MBBI, dl, OrImmInst, ScratchReg) | BuildMI(MBB, MBBI, dl, OrImmInst, ScratchReg) | ||||
▲ Show 20 Lines • Show All 231 Lines • ▼ Show 20 Lines | for (unsigned I = 0, E = CSI.size(); I != E; ++I) { | ||||
unsigned SpilledReg = CSI[I].getDstReg(); | unsigned SpilledReg = CSI[I].getDstReg(); | ||||
unsigned CFIRegister = MF.addFrameInst(MCCFIInstruction::createRegister( | unsigned CFIRegister = MF.addFrameInst(MCCFIInstruction::createRegister( | ||||
nullptr, MRI->getDwarfRegNum(Reg, true), | nullptr, MRI->getDwarfRegNum(Reg, true), | ||||
MRI->getDwarfRegNum(SpilledReg, true))); | MRI->getDwarfRegNum(SpilledReg, true))); | ||||
BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) | BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) | ||||
.addCFIIndex(CFIRegister); | .addCFIIndex(CFIRegister); | ||||
} else { | } else { | ||||
int Offset = MFI.getObjectOffset(CSI[I].getFrameIdx()); | int Offset = MFI.getObjectOffset(CSI[I].getFrameIdx()); | ||||
// We have changed the object offset above but we do not want to change | |||||
// the actual offsets in the CFI instruction so we have to undo the | |||||
// offset change here. | |||||
if (MovingStackUpdateDown) | |||||
Offset -= NegFrameSize; | |||||
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( | unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( | ||||
nullptr, MRI->getDwarfRegNum(Reg, true), Offset)); | nullptr, MRI->getDwarfRegNum(Reg, true), Offset)); | ||||
BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) | BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) | ||||
.addCFIIndex(CFIIndex); | .addCFIIndex(CFIIndex); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | void PPCFrameLowering::emitEpilogue(MachineFunction &MF, | ||||
// them. In such case, the final update of SP will be to add the frame | // them. In such case, the final update of SP will be to add the frame | ||||
// size to it. | // size to it. | ||||
// To simplify the code, set RBReg to the base register used to restore | // To simplify the code, set RBReg to the base register used to restore | ||||
// values from the stack, and set SPAdd to the value that needs to be added | // values from the stack, and set SPAdd to the value that needs to be added | ||||
// to the SP at the end. The default values are as if red zone was present. | // to the SP at the end. The default values are as if red zone was present. | ||||
unsigned RBReg = SPReg; | unsigned RBReg = SPReg; | ||||
unsigned SPAdd = 0; | unsigned SPAdd = 0; | ||||
// Check if we can move the stack update instruction up the epilogue | |||||
// past the callee saves. This will allow the move to LR instruction | |||||
// to be executed before the restores of the callee saves which means | |||||
// that the callee saves can hide the latency from the MTLR instrcution. | |||||
MachineBasicBlock::iterator StackUpdateLoc = MBBI; | |||||
if (stackUpdateCanBeMoved(MF)) { | |||||
const std::vector<CalleeSavedInfo> & Info = MFI.getCalleeSavedInfo(); | |||||
for (CalleeSavedInfo CSI : Info) { | |||||
int FrIdx = CSI.getFrameIdx(); | |||||
// If the frame index is not negative the callee saved info belongs to a | |||||
// stack object that is not a fixed stack object. We ignore non-fixed | |||||
// stack objects because we won't move the update of the stack pointer | |||||
// past them. | |||||
if (FrIdx >= 0) | |||||
continue; | |||||
if (MFI.isFixedObjectIndex(FrIdx) && MFI.getObjectOffset(FrIdx) < 0) | |||||
StackUpdateLoc--; | |||||
else { | |||||
// Abort the operation as we can't update all CSR restores. | |||||
StackUpdateLoc = MBBI; | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
if (FrameSize) { | if (FrameSize) { | ||||
// In the prologue, the loaded (or persistent) stack pointer value is | // In the prologue, the loaded (or persistent) stack pointer value is | ||||
// offset by the STDU/STDUX/STWU/STWUX instruction. For targets with red | // offset by the STDU/STDUX/STWU/STWUX instruction. For targets with red | ||||
// zone add this offset back now. | // zone add this offset back now. | ||||
// If this function contained a fastcc call and GuaranteedTailCallOpt is | // If this function contained a fastcc call and GuaranteedTailCallOpt is | ||||
// enabled (=> hasFastCall()==true) the fastcc call might contain a tail | // enabled (=> hasFastCall()==true) the fastcc call might contain a tail | ||||
// call which invalidates the stack pointer value in SP(0). So we use the | // call which invalidates the stack pointer value in SP(0). So we use the | ||||
Show All 13 Lines | if (FI->hasFastCall()) { | ||||
.addImm(FrameSize & 0xFFFF); | .addImm(FrameSize & 0xFFFF); | ||||
BuildMI(MBB, MBBI, dl, AddInst) | BuildMI(MBB, MBBI, dl, AddInst) | ||||
.addReg(RBReg) | .addReg(RBReg) | ||||
.addReg(FPReg) | .addReg(FPReg) | ||||
.addReg(ScratchReg); | .addReg(ScratchReg); | ||||
} | } | ||||
} else if (!isLargeFrame && !HasBP && !MFI.hasVarSizedObjects()) { | } else if (!isLargeFrame && !HasBP && !MFI.hasVarSizedObjects()) { | ||||
if (HasRedZone) { | if (HasRedZone) { | ||||
BuildMI(MBB, MBBI, dl, AddImmInst, SPReg) | BuildMI(MBB, StackUpdateLoc, dl, AddImmInst, SPReg) | ||||
.addReg(SPReg) | .addReg(SPReg) | ||||
.addImm(FrameSize); | .addImm(FrameSize); | ||||
} else { | } else { | ||||
// Make sure that adding FrameSize will not overflow the max offset | // Make sure that adding FrameSize will not overflow the max offset | ||||
// size. | // size. | ||||
assert(FPOffset <= 0 && BPOffset <= 0 && PBPOffset <= 0 && | assert(FPOffset <= 0 && BPOffset <= 0 && PBPOffset <= 0 && | ||||
"Local offsets should be negative"); | "Local offsets should be negative"); | ||||
SPAdd = FrameSize; | SPAdd = FrameSize; | ||||
FPOffset += FrameSize; | FPOffset += FrameSize; | ||||
BPOffset += FrameSize; | BPOffset += FrameSize; | ||||
PBPOffset += FrameSize; | PBPOffset += FrameSize; | ||||
} | } | ||||
} else { | } else { | ||||
// We don't want to use ScratchReg as a base register, because it | // We don't want to use ScratchReg as a base register, because it | ||||
// could happen to be R0. Use FP instead, but make sure to preserve it. | // could happen to be R0. Use FP instead, but make sure to preserve it. | ||||
if (!HasRedZone) { | if (!HasRedZone) { | ||||
// If FP is not saved, copy it to ScratchReg. | // If FP is not saved, copy it to ScratchReg. | ||||
if (!HasFP) | if (!HasFP) | ||||
BuildMI(MBB, MBBI, dl, OrInst, ScratchReg) | BuildMI(MBB, MBBI, dl, OrInst, ScratchReg) | ||||
.addReg(FPReg) | .addReg(FPReg) | ||||
.addReg(FPReg); | .addReg(FPReg); | ||||
RBReg = FPReg; | RBReg = FPReg; | ||||
} | } | ||||
BuildMI(MBB, MBBI, dl, LoadInst, RBReg) | BuildMI(MBB, StackUpdateLoc, dl, LoadInst, RBReg) | ||||
.addImm(0) | .addImm(0) | ||||
.addReg(SPReg); | .addReg(SPReg); | ||||
} | } | ||||
} | } | ||||
assert(RBReg != ScratchReg && "Should have avoided ScratchReg"); | assert(RBReg != ScratchReg && "Should have avoided ScratchReg"); | ||||
// If there is no red zone, ScratchReg may be needed for holding a useful | // If there is no red zone, ScratchReg may be needed for holding a useful | ||||
// value (although not the base register). Make sure it is not overwritten | // value (although not the base register). Make sure it is not overwritten | ||||
// too early. | // too early. | ||||
Show All 16 Lines | void PPCFrameLowering::emitEpilogue(MachineFunction &MF, | ||||
} | } | ||||
// Delay restoring of the LR if ScratchReg is needed. This is ok, since | // Delay restoring of the LR if ScratchReg is needed. This is ok, since | ||||
// LR is stored in the caller's stack frame. ScratchReg will be needed | // LR is stored in the caller's stack frame. ScratchReg will be needed | ||||
// if RBReg is anything other than SP. We shouldn't use ScratchReg as | // if RBReg is anything other than SP. We shouldn't use ScratchReg as | ||||
// a base register anyway, because it may happen to be R0. | // a base register anyway, because it may happen to be R0. | ||||
bool LoadedLR = false; | bool LoadedLR = false; | ||||
if (MustSaveLR && RBReg == SPReg && isInt<16>(LROffset+SPAdd)) { | if (MustSaveLR && RBReg == SPReg && isInt<16>(LROffset+SPAdd)) { | ||||
BuildMI(MBB, MBBI, dl, LoadInst, ScratchReg) | BuildMI(MBB, StackUpdateLoc, dl, LoadInst, ScratchReg) | ||||
.addImm(LROffset+SPAdd) | .addImm(LROffset+SPAdd) | ||||
.addReg(RBReg); | .addReg(RBReg); | ||||
LoadedLR = true; | LoadedLR = true; | ||||
} | } | ||||
if (MustSaveCR && !(SingleScratchReg && MustSaveLR)) { | if (MustSaveCR && !(SingleScratchReg && MustSaveLR)) { | ||||
// This will only occur for PPC64. | // This will only occur for PPC64. | ||||
assert(isPPC64 && "Expecting 64-bit mode"); | assert(isPPC64 && "Expecting 64-bit mode"); | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | void PPCFrameLowering::emitEpilogue(MachineFunction &MF, | ||||
if (MustSaveCR && | if (MustSaveCR && | ||||
!(SingleScratchReg && MustSaveLR)) // will only occur for PPC64 | !(SingleScratchReg && MustSaveLR)) // will only occur for PPC64 | ||||
for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i) | for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i) | ||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::MTOCRF8), MustSaveCRs[i]) | BuildMI(MBB, MBBI, dl, TII.get(PPC::MTOCRF8), MustSaveCRs[i]) | ||||
.addReg(TempReg, getKillRegState(i == e-1)); | .addReg(TempReg, getKillRegState(i == e-1)); | ||||
if (MustSaveLR) | if (MustSaveLR) | ||||
BuildMI(MBB, MBBI, dl, MTLRInst).addReg(ScratchReg); | BuildMI(MBB, StackUpdateLoc, dl, MTLRInst).addReg(ScratchReg); | ||||
// Callee pop calling convention. Pop parameter/linkage area. Used for tail | // Callee pop calling convention. Pop parameter/linkage area. Used for tail | ||||
// call optimization | // call optimization | ||||
if (IsReturnBlock) { | if (IsReturnBlock) { | ||||
unsigned RetOpcode = MBBI->getOpcode(); | unsigned RetOpcode = MBBI->getOpcode(); | ||||
if (MF.getTarget().Options.GuaranteedTailCallOpt && | if (MF.getTarget().Options.GuaranteedTailCallOpt && | ||||
(RetOpcode == PPC::BLR || RetOpcode == PPC::BLR8) && | (RetOpcode == PPC::BLR || RetOpcode == PPC::BLR8) && | ||||
MF.getFunction().getCallingConv() == CallingConv::Fast) { | MF.getFunction().getCallingConv() == CallingConv::Fast) { | ||||
▲ Show 20 Lines • Show All 392 Lines • ▼ Show 20 Lines | PPCFrameLowering::addScavengingSpillSlot(MachineFunction &MF, | ||||
// large. In case there is no free register for large-offset addressing, | // large. In case there is no free register for large-offset addressing, | ||||
// this slot is used for the necessary emergency spill. Also, we need the | // this slot is used for the necessary emergency spill. Also, we need the | ||||
// slot for dynamic stack allocations. | // slot for dynamic stack allocations. | ||||
// The scavenger might be invoked if the frame offset does not fit into | // The scavenger might be invoked if the frame offset does not fit into | ||||
// the 16-bit immediate. We don't know the complete frame size here | // the 16-bit immediate. We don't know the complete frame size here | ||||
// because we've not yet computed callee-saved register spills or the | // because we've not yet computed callee-saved register spills or the | ||||
// needed alignment padding. | // needed alignment padding. | ||||
unsigned StackSize = determineFrameLayout(MF, false, true); | unsigned StackSize = determineFrameLayout(MF, true); | ||||
MachineFrameInfo &MFI = MF.getFrameInfo(); | MachineFrameInfo &MFI = MF.getFrameInfo(); | ||||
if (MFI.hasVarSizedObjects() || spillsCR(MF) || spillsVRSAVE(MF) || | if (MFI.hasVarSizedObjects() || spillsCR(MF) || spillsVRSAVE(MF) || | ||||
hasNonRISpills(MF) || (hasSpills(MF) && !isInt<16>(StackSize))) { | hasNonRISpills(MF) || (hasSpills(MF) && !isInt<16>(StackSize))) { | ||||
const TargetRegisterClass &GPRC = PPC::GPRCRegClass; | const TargetRegisterClass &GPRC = PPC::GPRCRegClass; | ||||
const TargetRegisterClass &G8RC = PPC::G8RCRegClass; | const TargetRegisterClass &G8RC = PPC::G8RCRegClass; | ||||
const TargetRegisterClass &RC = Subtarget.isPPC64() ? G8RC : GPRC; | const TargetRegisterClass &RC = Subtarget.isPPC64() ? G8RC : GPRC; | ||||
const TargetRegisterInfo &TRI = *Subtarget.getRegisterInfo(); | const TargetRegisterInfo &TRI = *Subtarget.getRegisterInfo(); | ||||
unsigned Size = TRI.getSpillSize(RC); | unsigned Size = TRI.getSpillSize(RC); | ||||
▲ Show 20 Lines • Show All 327 Lines • Show Last 20 Lines |