Index: llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h +++ llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h @@ -31,15 +31,30 @@ class CalleeSavedInfo { unsigned Reg; int FrameIdx; + /// Flag indicating whether the register is actually restored in the epilog. + /// In most cases, if a register is saved, it is also restored. There are + /// some situations, though, when this is not the case. For example, the + /// LR register on ARM is usually saved, but on exit from the function its + /// saved value may be loaded directly into PC. Since liveness tracking of + /// physical registers treats callee-saved registers are live outside of + /// the function, LR would be treated as live-on-exit, even though in these + /// scenarios it is not. This flag is added to indicate that the saved + /// register described by this object is not restored in the epilog. + /// The long-term solution is to model the liveness of callee-saved registers + /// by implicit uses on the return instructions, however, the required + /// changes in the ARM backend would be quite extensive. + bool Restored; public: explicit CalleeSavedInfo(unsigned R, int FI = 0) - : Reg(R), FrameIdx(FI) {} + : Reg(R), FrameIdx(FI), Restored(true) {} // Accessors. unsigned getReg() const { return Reg; } int getFrameIdx() const { return FrameIdx; } void setFrameIdx(int FI) { FrameIdx = FI; } + bool isRestored() const { return Restored; } + void setRestored(bool R) { Restored = R; } }; /// The MachineFrameInfo class represents an abstract stack frame until @@ -667,6 +682,8 @@ const std::vector &getCalleeSavedInfo() const { return CSInfo; } + /// \copydoc getCalleeSavedInfo() + std::vector &getCalleeSavedInfo() { return CSInfo; } /// Used by prolog/epilog inserter to set the function's callee saved /// information. Index: llvm/trunk/include/llvm/Target/TargetFrameLowering.h =================================================================== --- llvm/trunk/include/llvm/Target/TargetFrameLowering.h +++ llvm/trunk/include/llvm/Target/TargetFrameLowering.h @@ -193,10 +193,12 @@ /// restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee /// saved registers and returns true if it isn't possible / profitable to do /// so by issuing a series of load instructions via loadRegToStackSlot(). + /// If it returns true, and any of the registers in CSI is not restored, + /// it sets the corresponding Restored flag in CSI to false. /// Returns false otherwise. virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { return false; } Index: llvm/trunk/lib/CodeGen/LivePhysRegs.cpp =================================================================== --- llvm/trunk/lib/CodeGen/LivePhysRegs.cpp +++ llvm/trunk/lib/CodeGen/LivePhysRegs.cpp @@ -192,7 +192,8 @@ const MachineFrameInfo &MFI = MF.getFrameInfo(); if (MFI.isCalleeSavedInfoValid()) { for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) - addReg(Info.getReg()); + if (Info.isRestored()) + addReg(Info.getReg()); } } } Index: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp =================================================================== --- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp +++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp @@ -489,7 +489,7 @@ /// Insert restore code for the callee-saved registers used in the function. static void insertCSRRestores(MachineBasicBlock &RestoreBlock, - ArrayRef CSI) { + std::vector &CSI) { MachineFunction &Fn = *RestoreBlock.getParent(); const TargetInstrInfo &TII = *Fn.getSubtarget().getInstrInfo(); const TargetFrameLowering *TFI = Fn.getSubtarget().getFrameLowering(); @@ -534,7 +534,7 @@ if (!F->hasFnAttribute(Attribute::Naked)) { MFI.setCalleeSavedInfoValid(true); - ArrayRef CSI = MFI.getCalleeSavedInfo(); + std::vector &CSI = MFI.getCalleeSavedInfo(); if (!CSI.empty()) { for (MachineBasicBlock *SaveBlock : SaveBlocks) { insertCSRSaves(*SaveBlock, CSI); Index: llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.h =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.h +++ llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.h @@ -50,7 +50,7 @@ bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const override; /// \brief Can this function use the red zone for local allocations. Index: llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -1092,7 +1092,7 @@ bool AArch64FrameLowering::restoreCalleeSavedRegisters( MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { MachineFunction &MF = *MBB.getParent(); const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); Index: llvm/trunk/lib/Target/ARM/ARMFrameLowering.h =================================================================== --- llvm/trunk/lib/Target/ARM/ARMFrameLowering.h +++ llvm/trunk/lib/Target/ARM/ARMFrameLowering.h @@ -38,7 +38,7 @@ bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const override; bool noFramePointerElim(const MachineFunction &MF) const override; @@ -69,7 +69,7 @@ bool(*Func)(unsigned, bool), unsigned NumAlignedDPRCS2Regs, unsigned MIFlags = 0) const; void emitPopInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, unsigned LdmOpc, + std::vector &CSI, unsigned LdmOpc, unsigned LdrOpc, bool isVarArg, bool NoGap, bool(*Func)(unsigned, bool), unsigned NumAlignedDPRCS2Regs) const; Index: llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp +++ llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp @@ -1019,7 +1019,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, unsigned LdmOpc, unsigned LdrOpc, bool isVarArg, bool NoGap, bool(*Func)(unsigned, bool), @@ -1090,9 +1090,18 @@ .add(predOps(ARMCC::AL)); for (unsigned i = 0, e = Regs.size(); i < e; ++i) MIB.addReg(Regs[i], getDefRegState(true)); - if (DeleteRet && MI != MBB.end()) { - MIB.copyImplicitOps(*MI); - MI->eraseFromParent(); + if (DeleteRet) { + if (MI != MBB.end()) { + MIB.copyImplicitOps(*MI); + MI->eraseFromParent(); + } + // If LR is not restored, mark it in CSI. + for (CalleeSavedInfo &I : CSI) { + if (I.getReg() != ARM::LR) + continue; + I.setRestored(false); + break; + } } MI = MIB; } else if (Regs.size() == 1) { @@ -1421,7 +1430,7 @@ bool ARMFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) return false; Index: llvm/trunk/lib/Target/ARM/Thumb1FrameLowering.h =================================================================== --- llvm/trunk/lib/Target/ARM/Thumb1FrameLowering.h +++ llvm/trunk/lib/Target/ARM/Thumb1FrameLowering.h @@ -36,7 +36,7 @@ const TargetRegisterInfo *TRI) const override; bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const override; bool hasReservedCallFrame(const MachineFunction &MF) const override; Index: llvm/trunk/lib/Target/ARM/Thumb1FrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/Thumb1FrameLowering.cpp +++ llvm/trunk/lib/Target/ARM/Thumb1FrameLowering.cpp @@ -780,7 +780,7 @@ bool Thumb1FrameLowering:: restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) return false; Index: llvm/trunk/lib/Target/AVR/AVRFrameLowering.h =================================================================== --- llvm/trunk/lib/Target/AVR/AVRFrameLowering.h +++ llvm/trunk/lib/Target/AVR/AVRFrameLowering.h @@ -30,7 +30,7 @@ bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const override; bool hasReservedCallFrame(const MachineFunction &MF) const override; bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override; Index: llvm/trunk/lib/Target/AVR/AVRFrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/AVR/AVRFrameLowering.cpp +++ llvm/trunk/lib/Target/AVR/AVRFrameLowering.cpp @@ -275,7 +275,7 @@ bool AVRFrameLowering::restoreCalleeSavedRegisters( MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) { return false; Index: llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.h =================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.h +++ llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.h @@ -48,7 +48,7 @@ } bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, const std::vector &CSI, + MachineBasicBlock::iterator MI, std::vector &CSI, const TargetRegisterInfo *TRI) const override { return true; } Index: llvm/trunk/lib/Target/MSP430/MSP430FrameLowering.h =================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430FrameLowering.h +++ llvm/trunk/lib/Target/MSP430/MSP430FrameLowering.h @@ -40,7 +40,7 @@ const TargetRegisterInfo *TRI) const override; bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const override; bool hasFP(const MachineFunction &MF) const override; Index: llvm/trunk/lib/Target/MSP430/MSP430FrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430FrameLowering.cpp +++ llvm/trunk/lib/Target/MSP430/MSP430FrameLowering.cpp @@ -206,7 +206,7 @@ bool MSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) return false; Index: llvm/trunk/lib/Target/Mips/Mips16FrameLowering.h =================================================================== --- llvm/trunk/lib/Target/Mips/Mips16FrameLowering.h +++ llvm/trunk/lib/Target/Mips/Mips16FrameLowering.h @@ -33,7 +33,7 @@ bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const override; bool hasReservedCallFrame(const MachineFunction &MF) const override; Index: llvm/trunk/lib/Target/Mips/Mips16FrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/Mips16FrameLowering.cpp +++ llvm/trunk/lib/Target/Mips/Mips16FrameLowering.cpp @@ -143,7 +143,7 @@ bool Mips16FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { // // Registers RA,S0,S1 are the callee saved registers and they will be restored Index: llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.h =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.h +++ llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.h @@ -106,7 +106,7 @@ bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const override; /// targetHandlesStackFrameRounding - Returns true if the target is Index: llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp +++ llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp @@ -2067,7 +2067,7 @@ bool PPCFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { // Currently, this function only handles SVR4 32- and 64-bit ABIs. Index: llvm/trunk/lib/Target/SystemZ/SystemZFrameLowering.h =================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZFrameLowering.h +++ llvm/trunk/lib/Target/SystemZ/SystemZFrameLowering.h @@ -35,7 +35,7 @@ const TargetRegisterInfo *TRI) const override; bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBII, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const override; void processFunctionBeforeFrameFinalized(MachineFunction &MF, Index: llvm/trunk/lib/Target/SystemZ/SystemZFrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZFrameLowering.cpp +++ llvm/trunk/lib/Target/SystemZ/SystemZFrameLowering.cpp @@ -220,7 +220,7 @@ bool SystemZFrameLowering:: restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) return false; Index: llvm/trunk/lib/Target/X86/X86FrameLowering.h =================================================================== --- llvm/trunk/lib/Target/X86/X86FrameLowering.h +++ llvm/trunk/lib/Target/X86/X86FrameLowering.h @@ -89,7 +89,7 @@ bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const override; bool hasFP(const MachineFunction &MF) const override; Index: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp +++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp @@ -1999,7 +1999,7 @@ bool X86FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) return false; Index: llvm/trunk/lib/Target/XCore/XCoreFrameLowering.h =================================================================== --- llvm/trunk/lib/Target/XCore/XCoreFrameLowering.h +++ llvm/trunk/lib/Target/XCore/XCoreFrameLowering.h @@ -38,7 +38,7 @@ const TargetRegisterInfo *TRI) const override; bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const override; MachineBasicBlock::iterator Index: llvm/trunk/lib/Target/XCore/XCoreFrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/XCore/XCoreFrameLowering.cpp +++ llvm/trunk/lib/Target/XCore/XCoreFrameLowering.cpp @@ -452,7 +452,7 @@ bool XCoreFrameLowering:: restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const{ MachineFunction *MF = MBB.getParent(); const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();