From: Krzysztof Parzyszek Date: Thu, 10 Aug 2017 16:17:32 +0000 (+0000) Subject: Add "Restored" flag to CalleeSavedInfo X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7b10f6e9190f4c508d7739b03fd5703086f97ecd;p=llvm Add "Restored" flag to CalleeSavedInfo The liveness-tracking code assumes that the registers that were saved in the function's prolog are live outside of the function. Specifically, that registers that were saved are also live-on-exit from the function. This isn't always the case as illustrated by the LR register on ARM. Differential Revision: https://reviews.llvm.org/D36160 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310619 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index c0789d71adf..9521c277988 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -31,15 +31,30 @@ class AllocaInst; 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 @@ public: 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. diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h index 4576f8c7582..31017cbc27b 100644 --- a/include/llvm/Target/TargetFrameLowering.h +++ b/include/llvm/Target/TargetFrameLowering.h @@ -193,10 +193,12 @@ public: /// 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; } diff --git a/lib/CodeGen/LivePhysRegs.cpp b/lib/CodeGen/LivePhysRegs.cpp index cde6ccd29df..870d8cc71c7 100644 --- a/lib/CodeGen/LivePhysRegs.cpp +++ b/lib/CodeGen/LivePhysRegs.cpp @@ -192,7 +192,8 @@ void LivePhysRegs::addLiveOutsNoPristines(const MachineBasicBlock &MBB) { const MachineFrameInfo &MFI = MF.getFrameInfo(); if (MFI.isCalleeSavedInfoValid()) { for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) - addReg(Info.getReg()); + if (Info.isRestored()) + addReg(Info.getReg()); } } } diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index cbb43203b5c..1b82cd2158a 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -489,7 +489,7 @@ static void insertCSRSaves(MachineBasicBlock &SaveBlock, /// 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 @@ static void doSpillCalleeSavedRegs(MachineFunction &Fn, RegScavenger *RS, 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); diff --git a/lib/Target/AArch64/AArch64FrameLowering.cpp b/lib/Target/AArch64/AArch64FrameLowering.cpp index 7c6a9999040..60f85115671 100644 --- a/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -1092,7 +1092,7 @@ bool AArch64FrameLowering::spillCalleeSavedRegisters( 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(); diff --git a/lib/Target/AArch64/AArch64FrameLowering.h b/lib/Target/AArch64/AArch64FrameLowering.h index f254ea9b70a..c351efb0c39 100644 --- a/lib/Target/AArch64/AArch64FrameLowering.h +++ b/lib/Target/AArch64/AArch64FrameLowering.h @@ -50,7 +50,7 @@ public: 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. diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp index f5a745f1d43..dc3e547ff27 100644 --- a/lib/Target/ARM/ARMFrameLowering.cpp +++ b/lib/Target/ARM/ARMFrameLowering.cpp @@ -1019,7 +1019,7 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB, 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 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB, .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::spillCalleeSavedRegisters(MachineBasicBlock &MBB, bool ARMFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) return false; diff --git a/lib/Target/ARM/ARMFrameLowering.h b/lib/Target/ARM/ARMFrameLowering.h index 21cd78da395..930ee531a3a 100644 --- a/lib/Target/ARM/ARMFrameLowering.h +++ b/lib/Target/ARM/ARMFrameLowering.h @@ -38,7 +38,7 @@ public: 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 @@ public: 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; diff --git a/lib/Target/ARM/Thumb1FrameLowering.cpp b/lib/Target/ARM/Thumb1FrameLowering.cpp index 5709b4e6179..7fc032d9809 100644 --- a/lib/Target/ARM/Thumb1FrameLowering.cpp +++ b/lib/Target/ARM/Thumb1FrameLowering.cpp @@ -780,7 +780,7 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB, bool Thumb1FrameLowering:: restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) return false; diff --git a/lib/Target/ARM/Thumb1FrameLowering.h b/lib/Target/ARM/Thumb1FrameLowering.h index 9de1ba1d700..e456e24ae73 100644 --- a/lib/Target/ARM/Thumb1FrameLowering.h +++ b/lib/Target/ARM/Thumb1FrameLowering.h @@ -36,7 +36,7 @@ public: 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; diff --git a/lib/Target/AVR/AVRFrameLowering.cpp b/lib/Target/AVR/AVRFrameLowering.cpp index 0ec8e8b08ce..5101cf586f1 100644 --- a/lib/Target/AVR/AVRFrameLowering.cpp +++ b/lib/Target/AVR/AVRFrameLowering.cpp @@ -275,7 +275,7 @@ bool AVRFrameLowering::spillCalleeSavedRegisters( bool AVRFrameLowering::restoreCalleeSavedRegisters( MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) { return false; diff --git a/lib/Target/AVR/AVRFrameLowering.h b/lib/Target/AVR/AVRFrameLowering.h index 850a43abebf..30ef441183a 100644 --- a/lib/Target/AVR/AVRFrameLowering.h +++ b/lib/Target/AVR/AVRFrameLowering.h @@ -30,7 +30,7 @@ public: 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; diff --git a/lib/Target/Hexagon/HexagonFrameLowering.h b/lib/Target/Hexagon/HexagonFrameLowering.h index 90a7cd83281..296edbe1eff 100644 --- a/lib/Target/Hexagon/HexagonFrameLowering.h +++ b/lib/Target/Hexagon/HexagonFrameLowering.h @@ -48,7 +48,7 @@ public: } bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, const std::vector &CSI, + MachineBasicBlock::iterator MI, std::vector &CSI, const TargetRegisterInfo *TRI) const override { return true; } diff --git a/lib/Target/MSP430/MSP430FrameLowering.cpp b/lib/Target/MSP430/MSP430FrameLowering.cpp index b4ff8f66c55..2421f09fbf5 100644 --- a/lib/Target/MSP430/MSP430FrameLowering.cpp +++ b/lib/Target/MSP430/MSP430FrameLowering.cpp @@ -206,7 +206,7 @@ MSP430FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, bool MSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) return false; diff --git a/lib/Target/MSP430/MSP430FrameLowering.h b/lib/Target/MSP430/MSP430FrameLowering.h index f77de18b4d1..fdc4aa52a19 100644 --- a/lib/Target/MSP430/MSP430FrameLowering.h +++ b/lib/Target/MSP430/MSP430FrameLowering.h @@ -40,7 +40,7 @@ public: 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; diff --git a/lib/Target/Mips/Mips16FrameLowering.cpp b/lib/Target/Mips/Mips16FrameLowering.cpp index 09e41e1423a..17dc90ace4a 100644 --- a/lib/Target/Mips/Mips16FrameLowering.cpp +++ b/lib/Target/Mips/Mips16FrameLowering.cpp @@ -143,7 +143,7 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB, 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 diff --git a/lib/Target/Mips/Mips16FrameLowering.h b/lib/Target/Mips/Mips16FrameLowering.h index b48ed4641ea..f7fa4dc3d86 100644 --- a/lib/Target/Mips/Mips16FrameLowering.h +++ b/lib/Target/Mips/Mips16FrameLowering.h @@ -33,7 +33,7 @@ public: 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; diff --git a/lib/Target/PowerPC/PPCFrameLowering.cpp b/lib/Target/PowerPC/PPCFrameLowering.cpp index b49c3345a17..756e35a6e6c 100644 --- a/lib/Target/PowerPC/PPCFrameLowering.cpp +++ b/lib/Target/PowerPC/PPCFrameLowering.cpp @@ -2067,7 +2067,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 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. diff --git a/lib/Target/PowerPC/PPCFrameLowering.h b/lib/Target/PowerPC/PPCFrameLowering.h index 28b0c57f0ff..fa813db5fef 100644 --- a/lib/Target/PowerPC/PPCFrameLowering.h +++ b/lib/Target/PowerPC/PPCFrameLowering.h @@ -106,7 +106,7 @@ public: 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 diff --git a/lib/Target/SystemZ/SystemZFrameLowering.cpp b/lib/Target/SystemZ/SystemZFrameLowering.cpp index 0cb2b5a14ce..3183c3acc69 100644 --- a/lib/Target/SystemZ/SystemZFrameLowering.cpp +++ b/lib/Target/SystemZ/SystemZFrameLowering.cpp @@ -220,7 +220,7 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB, bool SystemZFrameLowering:: restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) return false; diff --git a/lib/Target/SystemZ/SystemZFrameLowering.h b/lib/Target/SystemZ/SystemZFrameLowering.h index d43a176ad87..91c5a5d53a1 100644 --- a/lib/Target/SystemZ/SystemZFrameLowering.h +++ b/lib/Target/SystemZ/SystemZFrameLowering.h @@ -35,7 +35,7 @@ public: 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, diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index f294e819090..382c71ead5c 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/lib/Target/X86/X86FrameLowering.cpp @@ -1999,7 +1999,7 @@ bool X86FrameLowering::spillCalleeSavedRegisters( bool X86FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, + std::vector &CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) return false; diff --git a/lib/Target/X86/X86FrameLowering.h b/lib/Target/X86/X86FrameLowering.h index 7d214cabad5..773baff327d 100644 --- a/lib/Target/X86/X86FrameLowering.h +++ b/lib/Target/X86/X86FrameLowering.h @@ -89,7 +89,7 @@ public: 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; diff --git a/lib/Target/XCore/XCoreFrameLowering.cpp b/lib/Target/XCore/XCoreFrameLowering.cpp index 784612038c0..062b0958a03 100644 --- a/lib/Target/XCore/XCoreFrameLowering.cpp +++ b/lib/Target/XCore/XCoreFrameLowering.cpp @@ -452,7 +452,7 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB, 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(); diff --git a/lib/Target/XCore/XCoreFrameLowering.h b/lib/Target/XCore/XCoreFrameLowering.h index 8729d2208bb..27584f4e2b6 100644 --- a/lib/Target/XCore/XCoreFrameLowering.h +++ b/lib/Target/XCore/XCoreFrameLowering.h @@ -38,7 +38,7 @@ namespace llvm { 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