Changeset View
Changeset View
Standalone View
Standalone View
lib/Target/PowerPC/PPCFrameLowering.cpp
Show First 20 Lines • Show All 552 Lines • ▼ Show 20 Lines | for (MachineBasicBlock::iterator MBBI = BI->end(); MBBI != BI->begin(); ) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
void PPCFrameLowering::emitPrologue(MachineFunction &MF, | void PPCFrameLowering::emitPrologue(MachineFunction &MF, | ||||
MachineBasicBlock &MBB) const { | MachineBasicBlock &MBB) const { | ||||
assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); | |||||
MachineBasicBlock::iterator MBBI = MBB.begin(); | MachineBasicBlock::iterator MBBI = MBB.begin(); | ||||
MachineFrameInfo *MFI = MF.getFrameInfo(); | MachineFrameInfo *MFI = MF.getFrameInfo(); | ||||
const PPCInstrInfo &TII = | const PPCInstrInfo &TII = | ||||
*static_cast<const PPCInstrInfo *>(Subtarget.getInstrInfo()); | *static_cast<const PPCInstrInfo *>(Subtarget.getInstrInfo()); | ||||
const PPCRegisterInfo *RegInfo = | const PPCRegisterInfo *RegInfo = | ||||
static_cast<const PPCRegisterInfo *>(Subtarget.getRegisterInfo()); | static_cast<const PPCRegisterInfo *>(Subtarget.getRegisterInfo()); | ||||
MachineModuleInfo &MMI = MF.getMMI(); | MachineModuleInfo &MMI = MF.getMMI(); | ||||
Show All 15 Lines | void PPCFrameLowering::emitPrologue(MachineFunction &MF, | ||||
if (!isSVR4ABI) | if (!isSVR4ABI) | ||||
for (unsigned i = 0; MBBI != MBB.end(); ++i, ++MBBI) { | for (unsigned i = 0; MBBI != MBB.end(); ++i, ++MBBI) { | ||||
if (MBBI->getOpcode() == PPC::UPDATE_VRSAVE) { | if (MBBI->getOpcode() == PPC::UPDATE_VRSAVE) { | ||||
HandleVRSaveUpdate(MBBI, TII); | HandleVRSaveUpdate(MBBI, TII); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
// Move MBBI back to the beginning of the function. | // 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 = determineFrameLayout(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!"); | ||||
▲ Show 20 Lines • Show All 310 Lines • ▼ Show 20 Lines | for (unsigned I = 0, E = CSI.size(); I != E; ++I) { | ||||
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); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
void PPCFrameLowering::emitEpilogue(MachineFunction &MF, | void PPCFrameLowering::emitEpilogue(MachineFunction &MF, | ||||
MachineBasicBlock &MBB) const { | MachineBasicBlock &MBB) const { | ||||
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); | MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator(); | ||||
assert(MBBI != MBB.end() && "Returning block has no terminator"); | DebugLoc dl; | ||||
if (MBBI != MBB.end()) | |||||
dl = MBBI->getDebugLoc(); | |||||
const PPCInstrInfo &TII = | const PPCInstrInfo &TII = | ||||
*static_cast<const PPCInstrInfo *>(Subtarget.getInstrInfo()); | *static_cast<const PPCInstrInfo *>(Subtarget.getInstrInfo()); | ||||
const PPCRegisterInfo *RegInfo = | const PPCRegisterInfo *RegInfo = | ||||
static_cast<const PPCRegisterInfo *>(Subtarget.getRegisterInfo()); | static_cast<const PPCRegisterInfo *>(Subtarget.getRegisterInfo()); | ||||
unsigned RetOpcode = MBBI->getOpcode(); | |||||
DebugLoc dl; | |||||
assert((RetOpcode == PPC::BLR || | |||||
RetOpcode == PPC::BLR8 || | |||||
RetOpcode == PPC::TCRETURNri || | |||||
RetOpcode == PPC::TCRETURNdi || | |||||
RetOpcode == PPC::TCRETURNai || | |||||
RetOpcode == PPC::TCRETURNri8 || | |||||
RetOpcode == PPC::TCRETURNdi8 || | |||||
RetOpcode == PPC::TCRETURNai8) && | |||||
"Can only insert epilog into returning blocks"); | |||||
// Get alignment info so we know how to restore the SP. | // Get alignment info so we know how to restore the SP. | ||||
const MachineFrameInfo *MFI = MF.getFrameInfo(); | const MachineFrameInfo *MFI = MF.getFrameInfo(); | ||||
// Get the number of bytes allocated from the FrameInfo. | // Get the number of bytes allocated from the FrameInfo. | ||||
int FrameSize = MFI->getStackSize(); | int FrameSize = MFI->getStackSize(); | ||||
// Get processor type. | // Get processor type. | ||||
bool isPPC64 = Subtarget.isPPC64(); | bool isPPC64 = Subtarget.isPPC64(); | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | void PPCFrameLowering::emitEpilogue(MachineFunction &MF, | ||||
int PBPOffset = 0; | int PBPOffset = 0; | ||||
if (FI->usesPICBase()) { | if (FI->usesPICBase()) { | ||||
MachineFrameInfo *FFI = MF.getFrameInfo(); | MachineFrameInfo *FFI = MF.getFrameInfo(); | ||||
int PBPIndex = FI->getPICBasePointerSaveIndex(); | int PBPIndex = FI->getPICBasePointerSaveIndex(); | ||||
assert(PBPIndex && "No PIC Base Pointer Save Slot!"); | assert(PBPIndex && "No PIC Base Pointer Save Slot!"); | ||||
PBPOffset = FFI->getObjectOffset(PBPIndex); | PBPOffset = FFI->getObjectOffset(PBPIndex); | ||||
} | } | ||||
bool IsReturnBlock = MBBI->isReturn(); | |||||
chapuni: It is unsafe if MBBI points end iterator.
Tweaked in r247395. Please reconfirm. | |||||
if (IsReturnBlock) { | |||||
unsigned RetOpcode = MBBI->getOpcode(); | |||||
bool UsesTCRet = RetOpcode == PPC::TCRETURNri || | bool UsesTCRet = RetOpcode == PPC::TCRETURNri || | ||||
RetOpcode == PPC::TCRETURNdi || | RetOpcode == PPC::TCRETURNdi || | ||||
RetOpcode == PPC::TCRETURNai || | RetOpcode == PPC::TCRETURNai || | ||||
RetOpcode == PPC::TCRETURNri8 || | RetOpcode == PPC::TCRETURNri8 || | ||||
RetOpcode == PPC::TCRETURNdi8 || | RetOpcode == PPC::TCRETURNdi8 || | ||||
RetOpcode == PPC::TCRETURNai8; | RetOpcode == PPC::TCRETURNai8; | ||||
if (UsesTCRet) { | if (UsesTCRet) { | ||||
int MaxTCRetDelta = FI->getTailCallSPDelta(); | int MaxTCRetDelta = FI->getTailCallSPDelta(); | ||||
MachineOperand &StackAdjust = MBBI->getOperand(1); | MachineOperand &StackAdjust = MBBI->getOperand(1); | ||||
assert(StackAdjust.isImm() && "Expecting immediate value."); | assert(StackAdjust.isImm() && "Expecting immediate value."); | ||||
// Adjust stack pointer. | // Adjust stack pointer. | ||||
int StackAdj = StackAdjust.getImm(); | int StackAdj = StackAdjust.getImm(); | ||||
int Delta = StackAdj - MaxTCRetDelta; | int Delta = StackAdj - MaxTCRetDelta; | ||||
assert((Delta >= 0) && "Delta must be positive"); | assert((Delta >= 0) && "Delta must be positive"); | ||||
if (MaxTCRetDelta>0) | if (MaxTCRetDelta>0) | ||||
FrameSize += (StackAdj +Delta); | FrameSize += (StackAdj +Delta); | ||||
else | else | ||||
FrameSize += StackAdj; | FrameSize += StackAdj; | ||||
} | } | ||||
Not Done ReplyInline ActionsDoes RB stand for Return Block? Please use a more verbose name. hfinkel: Does RB stand for Return Block? Please use a more verbose name. | |||||
} | |||||
// 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 LD/LWZ immediate offset operand. | // indexed into with a simple LD/LWZ immediate offset operand. | ||||
bool isLargeFrame = !isInt<16>(FrameSize); | bool isLargeFrame = !isInt<16>(FrameSize); | ||||
if (FrameSize) { | if (FrameSize) { | ||||
// In the prologue, the loaded (or persistent) stack pointer value is offset | // In the prologue, the loaded (or persistent) stack pointer value is offset | ||||
// by the STDU/STDUX/STWU/STWUX instruction. Add this offset back now. | // by the STDU/STDUX/STWU/STWUX instruction. Add this offset back now. | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | 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, MBBI, 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) { | |||||
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) { | ||||
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); | PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); | ||||
unsigned CallerAllocatedAmt = FI->getMinReservedArea(); | unsigned CallerAllocatedAmt = FI->getMinReservedArea(); | ||||
if (CallerAllocatedAmt && isInt<16>(CallerAllocatedAmt)) { | if (CallerAllocatedAmt && isInt<16>(CallerAllocatedAmt)) { | ||||
BuildMI(MBB, MBBI, dl, AddImmInst, SPReg) | BuildMI(MBB, MBBI, dl, AddImmInst, SPReg) | ||||
.addReg(SPReg).addImm(CallerAllocatedAmt); | .addReg(SPReg).addImm(CallerAllocatedAmt); | ||||
} else { | } else { | ||||
BuildMI(MBB, MBBI, dl, LoadImmShiftedInst, ScratchReg) | BuildMI(MBB, MBBI, dl, LoadImmShiftedInst, ScratchReg) | ||||
.addImm(CallerAllocatedAmt >> 16); | .addImm(CallerAllocatedAmt >> 16); | ||||
BuildMI(MBB, MBBI, dl, OrImmInst, ScratchReg) | BuildMI(MBB, MBBI, dl, OrImmInst, ScratchReg) | ||||
.addReg(ScratchReg, RegState::Kill) | .addReg(ScratchReg, RegState::Kill) | ||||
.addImm(CallerAllocatedAmt & 0xFFFF); | .addImm(CallerAllocatedAmt & 0xFFFF); | ||||
BuildMI(MBB, MBBI, dl, AddInst) | BuildMI(MBB, MBBI, dl, AddInst) | ||||
.addReg(SPReg) | .addReg(SPReg) | ||||
.addReg(FPReg) | .addReg(FPReg) | ||||
.addReg(ScratchReg); | .addReg(ScratchReg); | ||||
} | } | ||||
} else if (RetOpcode == PPC::TCRETURNdi) { | } else if (RetOpcode == PPC::TCRETURNdi) { | ||||
MBBI = MBB.getLastNonDebugInstr(); | MBBI = MBB.getLastNonDebugInstr(); | ||||
MachineOperand &JumpTarget = MBBI->getOperand(0); | MachineOperand &JumpTarget = MBBI->getOperand(0); | ||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)). | BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)). | ||||
addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); | addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); | ||||
} else if (RetOpcode == PPC::TCRETURNri) { | } else if (RetOpcode == PPC::TCRETURNri) { | ||||
MBBI = MBB.getLastNonDebugInstr(); | MBBI = MBB.getLastNonDebugInstr(); | ||||
assert(MBBI->getOperand(0).isReg() && "Expecting register operand."); | assert(MBBI->getOperand(0).isReg() && "Expecting register operand."); | ||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR)); | BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR)); | ||||
} else if (RetOpcode == PPC::TCRETURNai) { | } else if (RetOpcode == PPC::TCRETURNai) { | ||||
MBBI = MBB.getLastNonDebugInstr(); | MBBI = MBB.getLastNonDebugInstr(); | ||||
MachineOperand &JumpTarget = MBBI->getOperand(0); | MachineOperand &JumpTarget = MBBI->getOperand(0); | ||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA)).addImm(JumpTarget.getImm()); | BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA)).addImm(JumpTarget.getImm()); | ||||
} else if (RetOpcode == PPC::TCRETURNdi8) { | } else if (RetOpcode == PPC::TCRETURNdi8) { | ||||
MBBI = MBB.getLastNonDebugInstr(); | MBBI = MBB.getLastNonDebugInstr(); | ||||
MachineOperand &JumpTarget = MBBI->getOperand(0); | MachineOperand &JumpTarget = MBBI->getOperand(0); | ||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)). | BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)). | ||||
addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); | addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); | ||||
} else if (RetOpcode == PPC::TCRETURNri8) { | } else if (RetOpcode == PPC::TCRETURNri8) { | ||||
MBBI = MBB.getLastNonDebugInstr(); | MBBI = MBB.getLastNonDebugInstr(); | ||||
assert(MBBI->getOperand(0).isReg() && "Expecting register operand."); | assert(MBBI->getOperand(0).isReg() && "Expecting register operand."); | ||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR8)); | BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR8)); | ||||
} else if (RetOpcode == PPC::TCRETURNai8) { | } else if (RetOpcode == PPC::TCRETURNai8) { | ||||
MBBI = MBB.getLastNonDebugInstr(); | MBBI = MBB.getLastNonDebugInstr(); | ||||
MachineOperand &JumpTarget = MBBI->getOperand(0); | MachineOperand &JumpTarget = MBBI->getOperand(0); | ||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA8)).addImm(JumpTarget.getImm()); | BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA8)).addImm(JumpTarget.getImm()); | ||||
} | } | ||||
} | } | ||||
} | |||||
void PPCFrameLowering::determineCalleeSaves(MachineFunction &MF, | void PPCFrameLowering::determineCalleeSaves(MachineFunction &MF, | ||||
BitVector &SavedRegs, | BitVector &SavedRegs, | ||||
RegScavenger *RS) const { | RegScavenger *RS) const { | ||||
TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); | TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); | ||||
const PPCRegisterInfo *RegInfo = | const PPCRegisterInfo *RegInfo = | ||||
static_cast<const PPCRegisterInfo *>(Subtarget.getRegisterInfo()); | static_cast<const PPCRegisterInfo *>(Subtarget.getRegisterInfo()); | ||||
▲ Show 20 Lines • Show All 536 Lines • ▼ Show 20 Lines | PPCFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, | ||||
if (CR2Spilled || CR3Spilled || CR4Spilled) { | if (CR2Spilled || CR3Spilled || CR4Spilled) { | ||||
bool is31 = needsFP(*MF); | bool is31 = needsFP(*MF); | ||||
restoreCRs(Subtarget.isPPC64(), is31, CR2Spilled, CR3Spilled, CR4Spilled, | restoreCRs(Subtarget.isPPC64(), is31, CR2Spilled, CR3Spilled, CR4Spilled, | ||||
MBB, I, CSI, CSIIndex); | MBB, I, CSI, CSIIndex); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool PPCFrameLowering::enableShrinkWrapping(const MachineFunction &MF) const { | |||||
return (MF.getSubtarget<PPCSubtarget>().isSVR4ABI() && | |||||
MF.getSubtarget<PPCSubtarget>().isPPC64()); | |||||
} |
It is unsafe if MBBI points end iterator.
Tweaked in r247395. Please reconfirm.