Thumb1 epilogue code generation needs to take into account that callee-saved

registers may be restored via a pop instruction, not just a tRestore.
This fixes nightly test 471.omnetep for Thumb1.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97867 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2010-03-06 03:28:39 +00:00
parent 75f0d6953a
commit e68bd74245

View File

@ -778,9 +778,19 @@ static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
} }
static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) { static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
return (MI->getOpcode() == ARM::tRestore && if (MI->getOpcode() == ARM::tRestore &&
MI->getOperand(1).isFI() && MI->getOperand(1).isFI() &&
isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs)); isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs))
return true;
else if (MI->getOpcode() == ARM::tPOP) {
// The first three operands are predicates and such. The last two are
// imp-def and imp-use of SP. Check everything in between.
for (int i = 3, e = MI->getNumOperands() - 2; i != e; ++i)
if (!isCalleeSavedRegister(MI->getOperand(i).getReg(), CSRegs))
return false;
return true;
}
return false;
} }
void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF, void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
@ -794,13 +804,13 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
int NumBytes = (int)MFI->getStackSize(); int NumBytes = (int)MFI->getStackSize();
const unsigned *CSRegs = getCalleeSavedRegs();
if (!AFI->hasStackFrame()) { if (!AFI->hasStackFrame()) {
if (NumBytes != 0) if (NumBytes != 0)
emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes); emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
} else { } else {
// Unwind MBBI to point to first LDR / VLDRD. // Unwind MBBI to point to first LDR / VLDRD.
const unsigned *CSRegs = getCalleeSavedRegs();
if (MBBI != MBB.begin()) { if (MBBI != MBB.begin()) {
do do
--MBBI; --MBBI;
@ -836,6 +846,9 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
} }
if (VARegSaveSize) { if (VARegSaveSize) {
// Move back past the callee-saved register restoration
while (MBBI != MBB.end() && isCSRestore(MBBI, CSRegs))
++MBBI;
// Epilogue for vararg functions: pop LR to R3 and branch off it. // Epilogue for vararg functions: pop LR to R3 and branch off it.
AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP))) AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)))
.addReg(0) // No write back. .addReg(0) // No write back.
@ -845,6 +858,7 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)) BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg))
.addReg(ARM::R3, RegState::Kill); .addReg(ARM::R3, RegState::Kill);
// erase the old tBX_RET instruction
MBB.erase(MBBI); MBB.erase(MBBI);
} }
} }