]> granicus.if.org Git - llvm/commitdiff
Add "Restored" flag to CalleeSavedInfo
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>
Thu, 10 Aug 2017 16:17:32 +0000 (16:17 +0000)
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>
Thu, 10 Aug 2017 16:17:32 +0000 (16:17 +0000)
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

25 files changed:
include/llvm/CodeGen/MachineFrameInfo.h
include/llvm/Target/TargetFrameLowering.h
lib/CodeGen/LivePhysRegs.cpp
lib/CodeGen/PrologEpilogInserter.cpp
lib/Target/AArch64/AArch64FrameLowering.cpp
lib/Target/AArch64/AArch64FrameLowering.h
lib/Target/ARM/ARMFrameLowering.cpp
lib/Target/ARM/ARMFrameLowering.h
lib/Target/ARM/Thumb1FrameLowering.cpp
lib/Target/ARM/Thumb1FrameLowering.h
lib/Target/AVR/AVRFrameLowering.cpp
lib/Target/AVR/AVRFrameLowering.h
lib/Target/Hexagon/HexagonFrameLowering.h
lib/Target/MSP430/MSP430FrameLowering.cpp
lib/Target/MSP430/MSP430FrameLowering.h
lib/Target/Mips/Mips16FrameLowering.cpp
lib/Target/Mips/Mips16FrameLowering.h
lib/Target/PowerPC/PPCFrameLowering.cpp
lib/Target/PowerPC/PPCFrameLowering.h
lib/Target/SystemZ/SystemZFrameLowering.cpp
lib/Target/SystemZ/SystemZFrameLowering.h
lib/Target/X86/X86FrameLowering.cpp
lib/Target/X86/X86FrameLowering.h
lib/Target/XCore/XCoreFrameLowering.cpp
lib/Target/XCore/XCoreFrameLowering.h

index c0789d71adf1c6c38d6193f68fcb17aad6e06041..9521c277988a89f68c79fc6201ac08c01b375fb4 100644 (file)
@@ -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<CalleeSavedInfo> &getCalleeSavedInfo() const {
     return CSInfo;
   }
+  /// \copydoc getCalleeSavedInfo()
+  std::vector<CalleeSavedInfo> &getCalleeSavedInfo() { return CSInfo; }
 
   /// Used by prolog/epilog inserter to set the function's callee saved
   /// information.
index 4576f8c7582bee51ee3914e7d705101d4712fd25..31017cbc27b85198973760fd877b202107fdf9cf 100644 (file)
@@ -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<CalleeSavedInfo> &CSI,
+                                           std::vector<CalleeSavedInfo> &CSI,
                                         const TargetRegisterInfo *TRI) const {
     return false;
   }
index cde6ccd29dfd8b5ac431854cc301212f1be92dc5..870d8cc71c72434e84d5712c2fb275e215a4581c 100644 (file)
@@ -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());
     }
   }
 }
index cbb43203b5ca4a0d9f4d5bfa7ab6e2bac7987bdc..1b82cd2158ae8bc7a6ccc1cdfe2127bc516f135b 100644 (file)
@@ -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<CalleeSavedInfo> CSI) {
+                              std::vector<CalleeSavedInfo> &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<CalleeSavedInfo> CSI = MFI.getCalleeSavedInfo();
+    std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
     if (!CSI.empty()) {
       for (MachineBasicBlock *SaveBlock : SaveBlocks) {
         insertCSRSaves(*SaveBlock, CSI);
index 7c6a99990406c2f593e337bf9762ae3c49022426..60f85115671bbecde57ac0b3eec89e722219a62e 100644 (file)
@@ -1092,7 +1092,7 @@ bool AArch64FrameLowering::spillCalleeSavedRegisters(
 
 bool AArch64FrameLowering::restoreCalleeSavedRegisters(
     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
-    const std::vector<CalleeSavedInfo> &CSI,
+    std::vector<CalleeSavedInfo> &CSI,
     const TargetRegisterInfo *TRI) const {
   MachineFunction &MF = *MBB.getParent();
   const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
index f254ea9b70aa730894a89155b30bb951a4c656eb..c351efb0c39b15c9ba32f21a3090fe26120d7e7e 100644 (file)
@@ -50,7 +50,7 @@ public:
 
   bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                   MachineBasicBlock::iterator MI,
-                                  const std::vector<CalleeSavedInfo> &CSI,
+                                  std::vector<CalleeSavedInfo> &CSI,
                                   const TargetRegisterInfo *TRI) const override;
 
   /// \brief Can this function use the red zone for local allocations.
index f5a745f1d4371bb85f305918beaf7709a5e59e73..dc3e547ff27c01a09ee46148efa9402bb4acd4fb 100644 (file)
@@ -1019,7 +1019,7 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB,
 
 void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
                                    MachineBasicBlock::iterator MI,
-                                   const std::vector<CalleeSavedInfo> &CSI,
+                                   std::vector<CalleeSavedInfo> &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<CalleeSavedInfo> &CSI,
+                                        std::vector<CalleeSavedInfo> &CSI,
                                         const TargetRegisterInfo *TRI) const {
   if (CSI.empty())
     return false;
index 21cd78da395c8c38e28097ee6cbe6bb8b2617dc1..930ee531a3aa5e266741d94bd9694ff3796028b6 100644 (file)
@@ -38,7 +38,7 @@ public:
 
   bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                   MachineBasicBlock::iterator MI,
-                                  const std::vector<CalleeSavedInfo> &CSI,
+                                  std::vector<CalleeSavedInfo> &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<CalleeSavedInfo> &CSI, unsigned LdmOpc,
+                   std::vector<CalleeSavedInfo> &CSI, unsigned LdmOpc,
                    unsigned LdrOpc, bool isVarArg, bool NoGap,
                    bool(*Func)(unsigned, bool),
                    unsigned NumAlignedDPRCS2Regs) const;
index 5709b4e617987b01b8f432069d475fceb38888b1..7fc032d98099429c3249780afdb060e5a65b67f7 100644 (file)
@@ -780,7 +780,7 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB,
 bool Thumb1FrameLowering::
 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                             MachineBasicBlock::iterator MI,
-                            const std::vector<CalleeSavedInfo> &CSI,
+                            std::vector<CalleeSavedInfo> &CSI,
                             const TargetRegisterInfo *TRI) const {
   if (CSI.empty())
     return false;
index 9de1ba1d7009aadaec6841a65b50396fd4faf174..e456e24ae735b84d506a77ffeecf9b324a53d5a4 100644 (file)
@@ -36,7 +36,7 @@ public:
                                  const TargetRegisterInfo *TRI) const override;
   bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                   MachineBasicBlock::iterator MI,
-                                  const std::vector<CalleeSavedInfo> &CSI,
+                                  std::vector<CalleeSavedInfo> &CSI,
                                   const TargetRegisterInfo *TRI) const override;
 
   bool hasReservedCallFrame(const MachineFunction &MF) const override;
index 0ec8e8b08ceb451d4e870ac91a3e5f85973cf8ec..5101cf586f11ef18778e502f74014a1cfb9af849 100644 (file)
@@ -275,7 +275,7 @@ bool AVRFrameLowering::spillCalleeSavedRegisters(
 
 bool AVRFrameLowering::restoreCalleeSavedRegisters(
     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
-    const std::vector<CalleeSavedInfo> &CSI,
+    std::vector<CalleeSavedInfo> &CSI,
     const TargetRegisterInfo *TRI) const {
   if (CSI.empty()) {
     return false;
index 850a43abebfadd05521caacd31f716ac9108d7db..30ef441183a9d9bc53a254aca15d5ac667662878 100644 (file)
@@ -30,7 +30,7 @@ public:
   bool
   restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                               MachineBasicBlock::iterator MI,
-                              const std::vector<CalleeSavedInfo> &CSI,
+                              std::vector<CalleeSavedInfo> &CSI,
                               const TargetRegisterInfo *TRI) const override;
   bool hasReservedCallFrame(const MachineFunction &MF) const override;
   bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override;
index 90a7cd8328138a558af9e92f99da680921621c90..296edbe1effb4667ac899d1dc7fc08f7c28c6589 100644 (file)
@@ -48,7 +48,7 @@ public:
   }
 
   bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
-      MachineBasicBlock::iterator MI, const std::vector<CalleeSavedInfo> &CSI,
+      MachineBasicBlock::iterator MI, std::vector<CalleeSavedInfo> &CSI,
       const TargetRegisterInfo *TRI) const override {
     return true;
   }
index b4ff8f66c55f011ee1da4683b90d86daf857286f..2421f09fbf59aba2a7e5b151d217aad5eebf63bc 100644 (file)
@@ -206,7 +206,7 @@ MSP430FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
 bool
 MSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                                  MachineBasicBlock::iterator MI,
-                                        const std::vector<CalleeSavedInfo> &CSI,
+                                        std::vector<CalleeSavedInfo> &CSI,
                                         const TargetRegisterInfo *TRI) const {
   if (CSI.empty())
     return false;
index f77de18b4d161f51c7bfd833c828ee0ab5584d0e..fdc4aa52a195009678d5933e59a67a3605936eb8 100644 (file)
@@ -40,7 +40,7 @@ public:
                                  const TargetRegisterInfo *TRI) const override;
   bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                   MachineBasicBlock::iterator MI,
-                                  const std::vector<CalleeSavedInfo> &CSI,
+                                  std::vector<CalleeSavedInfo> &CSI,
                                   const TargetRegisterInfo *TRI) const override;
 
   bool hasFP(const MachineFunction &MF) const override;
index 09e41e1423aee154cd928a03f3ca1299b3914e89..17dc90ace4a06da34151a0200b3f07db6e935c5b 100644 (file)
@@ -143,7 +143,7 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB,
 
 bool Mips16FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                           MachineBasicBlock::iterator MI,
-                                       const std::vector<CalleeSavedInfo> &CSI,
+                                       std::vector<CalleeSavedInfo> &CSI,
                                        const TargetRegisterInfo *TRI) const {
   //
   // Registers RA,S0,S1 are the callee saved registers and they will be restored
index b48ed4641ea7041b45a2e90a84600cd8b307bcf8..f7fa4dc3d86d9ac28678b734e5111fd3f66eb144 100644 (file)
@@ -33,7 +33,7 @@ public:
 
   bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                   MachineBasicBlock::iterator MI,
-                                  const std::vector<CalleeSavedInfo> &CSI,
+                                  std::vector<CalleeSavedInfo> &CSI,
                                   const TargetRegisterInfo *TRI) const override;
 
   bool hasReservedCallFrame(const MachineFunction &MF) const override;
index b49c3345a17dd6cf21657e7b70fd5e0abde4cbb0..756e35a6e6c60cb64790671c0de5bc11fce6276d 100644 (file)
@@ -2067,7 +2067,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
 bool
 PPCFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                         MachineBasicBlock::iterator MI,
-                                        const std::vector<CalleeSavedInfo> &CSI,
+                                        std::vector<CalleeSavedInfo> &CSI,
                                         const TargetRegisterInfo *TRI) const {
 
   // Currently, this function only handles SVR4 32- and 64-bit ABIs.
index 28b0c57f0ffb5af8edc2bc9f57692cb9b09d0eb8..fa813db5fef369616f17f6ebb4a48b10a2f51c48 100644 (file)
@@ -106,7 +106,7 @@ public:
 
   bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                   MachineBasicBlock::iterator MI,
-                                  const std::vector<CalleeSavedInfo> &CSI,
+                                  std::vector<CalleeSavedInfo> &CSI,
                                   const TargetRegisterInfo *TRI) const override;
 
   /// targetHandlesStackFrameRounding - Returns true if the target is
index 0cb2b5a14ce7389d5521a1eb8b24df67e670ce3e..3183c3acc69a7ff59045cef0dd6d4270f29b9a4c 100644 (file)
@@ -220,7 +220,7 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB,
 bool SystemZFrameLowering::
 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                             MachineBasicBlock::iterator MBBI,
-                            const std::vector<CalleeSavedInfo> &CSI,
+                            std::vector<CalleeSavedInfo> &CSI,
                             const TargetRegisterInfo *TRI) const {
   if (CSI.empty())
     return false;
index d43a176ad87483255eabe3ceb71fc5202aed3f9d..91c5a5d53a157902dc38bb4ae70e721a7de25581 100644 (file)
@@ -35,7 +35,7 @@ public:
                                  const TargetRegisterInfo *TRI) const override;
   bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                    MachineBasicBlock::iterator MBBII,
-                                   const std::vector<CalleeSavedInfo> &CSI,
+                                   std::vector<CalleeSavedInfo> &CSI,
                                    const TargetRegisterInfo *TRI) const
     override;
   void processFunctionBeforeFrameFinalized(MachineFunction &MF,
index f294e819090bc03d0faf940f2ca6f00c8592ebcc..382c71ead5cbb0a0f448d334aec5be4a272259fd 100644 (file)
@@ -1999,7 +1999,7 @@ bool X86FrameLowering::spillCalleeSavedRegisters(
 
 bool X86FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                                MachineBasicBlock::iterator MI,
-                                        const std::vector<CalleeSavedInfo> &CSI,
+                                          std::vector<CalleeSavedInfo> &CSI,
                                           const TargetRegisterInfo *TRI) const {
   if (CSI.empty())
     return false;
index 7d214cabad536ab486671b1cb8c63d867928a90d..773baff327d65bb1f66b589aa5af978784c1032f 100644 (file)
@@ -89,7 +89,7 @@ public:
 
   bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                   MachineBasicBlock::iterator MI,
-                                  const std::vector<CalleeSavedInfo> &CSI,
+                                  std::vector<CalleeSavedInfo> &CSI,
                                   const TargetRegisterInfo *TRI) const override;
 
   bool hasFP(const MachineFunction &MF) const override;
index 784612038c09c75d7cc2382f6bab6ee8d615ebec..062b0958a0329baec0b514a8b9fece6f758d01c8 100644 (file)
@@ -452,7 +452,7 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB,
 bool XCoreFrameLowering::
 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                             MachineBasicBlock::iterator MI,
-                            const std::vector<CalleeSavedInfo> &CSI,
+                            std::vector<CalleeSavedInfo> &CSI,
                             const TargetRegisterInfo *TRI) const{
   MachineFunction *MF = MBB.getParent();
   const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
index 8729d2208bb2396f270fbd7e5f3996adb6a5c258..27584f4e2b6c0dbb161eec5ff3716f818be6c378 100644 (file)
@@ -38,7 +38,7 @@ namespace llvm {
                                   const TargetRegisterInfo *TRI) const override;
     bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                   MachineBasicBlock::iterator MI,
-                                  const std::vector<CalleeSavedInfo> &CSI,
+                                  std::vector<CalleeSavedInfo> &CSI,
                                   const TargetRegisterInfo *TRI) const override;
 
     MachineBasicBlock::iterator