X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FThumb1FrameLowering.cpp;h=996428dbeb1291f3c8f7f07981e86f3a54266589;hb=1decd56b8dec415b9d2270d636226b9fdb0b9c25;hp=0a05c0b84953fd0f2f38cb09db540bd0387c6044;hpb=ad249171e4fa718290be2f1b276c1b7864dd27f7;p=oota-llvm.git diff --git a/lib/Target/ARM/Thumb1FrameLowering.cpp b/lib/Target/ARM/Thumb1FrameLowering.cpp index 0a05c0b8495..996428dbeb1 100644 --- a/lib/Target/ARM/Thumb1FrameLowering.cpp +++ b/lib/Target/ARM/Thumb1FrameLowering.cpp @@ -16,6 +16,7 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" using namespace llvm; @@ -83,6 +84,8 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock::iterator MBBI = MBB.begin(); MachineFrameInfo *MFI = MF.getFrameInfo(); ARMFunctionInfo *AFI = MF.getInfo(); + MachineModuleInfo &MMI = MF.getMMI(); + const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); const Thumb1RegisterInfo *RegInfo = static_cast(MF.getTarget().getRegisterInfo()); const Thumb1InstrInfo &TII = @@ -95,6 +98,7 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); unsigned FramePtr = RegInfo->getFrameRegister(MF); unsigned BasePtr = RegInfo->getBaseRegister(); + int CFAOffset = 0; // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4. NumBytes = (NumBytes + 3) & ~3; @@ -105,14 +109,28 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0; int FramePtrSpillFI = 0; - if (ArgRegsSaveSize) + if (ArgRegsSaveSize) { emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -ArgRegsSaveSize, MachineInstr::FrameSetup); + MCSymbol *SPLabel = MMI.getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)) + .addSym(SPLabel); + CFAOffset -= ArgRegsSaveSize; + MMI.addFrameInst( + MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset)); + } if (!AFI->hasStackFrame()) { - if (NumBytes != 0) + if (NumBytes != 0) { emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes, MachineInstr::FrameSetup); + MCSymbol *SPLabel = MMI.getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)) + .addSym(SPLabel); + CFAOffset -= NumBytes; + MMI.addFrameInst( + MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset)); + } return; } @@ -120,6 +138,15 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { unsigned Reg = CSI[i].getReg(); int FI = CSI[i].getFrameIdx(); switch (Reg) { + case ARM::R8: + case ARM::R9: + case ARM::R10: + case ARM::R11: + if (STI.isTargetMachO()) { + GPRCS2Size += 4; + break; + } + // fallthrough case ARM::R4: case ARM::R5: case ARM::R6: @@ -129,17 +156,6 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { FramePtrSpillFI = FI; GPRCS1Size += 4; break; - case ARM::R8: - case ARM::R9: - case ARM::R10: - case ARM::R11: - if (Reg == FramePtr) - FramePtrSpillFI = FI; - if (STI.isTargetIOS()) - GPRCS2Size += 4; - else - GPRCS1Size += 4; - break; default: DPRCSSize += 8; } @@ -165,27 +181,87 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { NumBytes = DPRCSOffset; int FramePtrOffsetInBlock = 0; - if (tryFoldSPUpdateIntoPushPop(STI, MF, prior(MBBI), NumBytes)) { + unsigned adjustedGPRCS1Size = GPRCS1Size; + if (tryFoldSPUpdateIntoPushPop(STI, MF, std::prev(MBBI), NumBytes)) { FramePtrOffsetInBlock = NumBytes; + adjustedGPRCS1Size += NumBytes; NumBytes = 0; } + MCSymbol *SPLabel = MMI.getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SPLabel); + if (adjustedGPRCS1Size) { + CFAOffset -= adjustedGPRCS1Size; + MMI.addFrameInst( + MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset)); + } + for (std::vector::const_iterator I = CSI.begin(), + E = CSI.end(); I != E; ++I) { + unsigned Reg = I->getReg(); + int FI = I->getFrameIdx(); + switch (Reg) { + case ARM::R8: + case ARM::R9: + case ARM::R10: + case ARM::R11: + case ARM::R12: + if (STI.isTargetMachO()) + break; + // fallthough + case ARM::R0: + case ARM::R1: + case ARM::R2: + case ARM::R3: + case ARM::R4: + case ARM::R5: + case ARM::R6: + case ARM::R7: + case ARM::LR: + MMI.addFrameInst(MCCFIInstruction::createOffset(SPLabel, + MRI->getDwarfRegNum(Reg, true), + MFI->getObjectOffset(FI) - ArgRegsSaveSize)); + break; + } + } + + // Adjust FP so it point to the stack slot that contains the previous FP. if (HasFP) { FramePtrOffsetInBlock += MFI->getObjectOffset(FramePtrSpillFI) + GPRCS1Size; AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr) .addReg(ARM::SP).addImm(FramePtrOffsetInBlock / 4) .setMIFlags(MachineInstr::FrameSetup)); + MCSymbol *SPLabel = MMI.getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)) + .addSym(SPLabel); + if(FramePtrOffsetInBlock) { + CFAOffset += FramePtrOffsetInBlock; + MMI.addFrameInst( + MCCFIInstruction::createDefCfa(SPLabel, + MRI->getDwarfRegNum(FramePtr, true), CFAOffset)); + } else + MMI.addFrameInst( + MCCFIInstruction::createDefCfaRegister(SPLabel, + MRI->getDwarfRegNum(FramePtr, true))); if (NumBytes > 508) // If offset is > 508 then sp cannot be adjusted in a single instruction, // try restoring from fp instead. AFI->setShouldRestoreSPFromFP(true); } - if (NumBytes) + if (NumBytes) { // Insert it after all the callee-save spills. emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes, MachineInstr::FrameSetup); + if (!HasFP) { + MCSymbol *SPLabel = MMI.getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)) + .addSym(SPLabel); + CFAOffset -= NumBytes; + MMI.addFrameInst( + MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset)); + } + } if (STI.isTargetELF() && HasFP) MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() - @@ -289,8 +365,8 @@ void Thumb1FrameLowering::emitEpilogue(MachineFunction &MF, } else { if (MBBI->getOpcode() == ARM::tBX_RET && &MBB.front() != MBBI && - prior(MBBI)->getOpcode() == ARM::tPOP) { - MachineBasicBlock::iterator PMBBI = prior(MBBI); + std::prev(MBBI)->getOpcode() == ARM::tPOP) { + MachineBasicBlock::iterator PMBBI = std::prev(MBBI); if (!tryFoldSPUpdateIntoPushPop(STI, MF, PMBBI, NumBytes)) emitSPUpdate(MBB, PMBBI, TII, dl, *RegInfo, NumBytes); } else if (!tryFoldSPUpdateIntoPushPop(STI, MF, MBBI, NumBytes)) @@ -304,9 +380,9 @@ void Thumb1FrameLowering::emitEpilogue(MachineFunction &MF, // we need to update the SP after popping the value. Therefore, we // pop the old LR into R3 as a temporary. - // Move back past the callee-saved register restoration - while (MBBI != MBB.end() && isCSRestore(MBBI, CSRegs)) - ++MBBI; + // Get the last instruction, tBX_RET + MBBI = MBB.getLastNonDebugInstr(); + assert (MBBI->getOpcode() == ARM::tBX_RET); // Epilogue for vararg functions: pop LR to R3 and branch off it. AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP))) .addReg(ARM::R3, RegState::Define);