X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FThumb1FrameLowering.cpp;h=996428dbeb1291f3c8f7f07981e86f3a54266589;hb=1decd56b8dec415b9d2270d636226b9fdb0b9c25;hp=1e2a8b03e1a0470cd7d3796dffa5e2751adc91f4;hpb=f65e4932f83ac0c36594d97fca73dc9a9fd26672;p=oota-llvm.git diff --git a/lib/Target/ARM/Thumb1FrameLowering.cpp b/lib/Target/ARM/Thumb1FrameLowering.cpp index 1e2a8b03e1a..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,17 +84,21 @@ 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 = *static_cast(MF.getTarget().getInstrInfo()); - unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(); + unsigned Align = MF.getTarget().getFrameLowering()->getStackAlignment(); + unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(Align); unsigned NumBytes = MFI->getStackSize(); const std::vector &CSI = MFI->getCalleeSavedInfo(); 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; @@ -104,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; } @@ -119,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: @@ -126,25 +154,9 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { case ARM::LR: if (Reg == FramePtr) FramePtrSpillFI = FI; - AFI->addGPRCalleeSavedArea1Frame(FI); GPRCS1Size += 4; break; - case ARM::R8: - case ARM::R9: - case ARM::R10: - case ARM::R11: - if (Reg == FramePtr) - FramePtrSpillFI = FI; - if (STI.isTargetIOS()) { - AFI->addGPRCalleeSavedArea2Frame(FI); - GPRCS2Size += 4; - } else { - AFI->addGPRCalleeSavedArea1Frame(FI); - GPRCS1Size += 4; - } - break; default: - AFI->addDPRCalleeSavedAreaFrame(FI); DPRCSSize += 8; } } @@ -168,21 +180,88 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset); NumBytes = DPRCSOffset; + int FramePtrOffsetInBlock = 0; + 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) - .addFrameIndex(FramePtrSpillFI).addImm(0) + .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() - @@ -212,13 +291,6 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { AFI->setShouldRestoreSPFromFP(true); } -static bool isCalleeSavedRegister(unsigned Reg, const uint16_t *CSRegs) { - for (unsigned i = 0; CSRegs[i]; ++i) - if (Reg == CSRegs[i]) - return true; - return false; -} - static bool isCSRestore(MachineInstr *MI, const uint16_t *CSRegs) { if (MI->getOpcode() == ARM::tLDRspi && MI->getOperand(1).isFI() && @@ -249,7 +321,8 @@ void Thumb1FrameLowering::emitEpilogue(MachineFunction &MF, const Thumb1InstrInfo &TII = *static_cast(MF.getTarget().getInstrInfo()); - unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(); + unsigned Align = MF.getTarget().getFrameLowering()->getStackAlignment(); + unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(Align); int NumBytes = (int)MFI->getStackSize(); const uint16_t *CSRegs = RegInfo->getCalleeSavedRegs(); unsigned FramePtr = RegInfo->getFrameRegister(MF); @@ -292,10 +365,11 @@ 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); - emitSPUpdate(MBB, PMBBI, TII, dl, *RegInfo, NumBytes); - } else + 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)) emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, NumBytes); } } @@ -306,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);