[llvm] r272756 - Don't force SP-relative addressing for statepoints

Sanjoy Das via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 14 22:35:14 PDT 2016


Author: sanjoy
Date: Wed Jun 15 00:35:14 2016
New Revision: 272756

URL: http://llvm.org/viewvc/llvm-project?rev=272756&view=rev
Log:
Don't force SP-relative addressing for statepoints

Summary:
...  when the offset is not statically known.

Prioritize addresses relative to the stack pointer in the stackmap, but
fallback gracefully to other modes of addressing if the offset to the
stack pointer is not a known constant.

Patch by Oscar Blumberg!

Reviewers: sanjoy

Subscribers: llvm-commits, majnemer, rnk, sanjoy, thanm

Differential Revision: http://reviews.llvm.org/D21259

Modified:
    llvm/trunk/include/llvm/Target/TargetFrameLowering.h
    llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
    llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp
    llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
    llvm/trunk/lib/Target/X86/X86FrameLowering.h
    llvm/trunk/test/CodeGen/X86/deopt-bundles.ll

Modified: llvm/trunk/include/llvm/Target/TargetFrameLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetFrameLowering.h?rev=272756&r1=272755&r2=272756&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetFrameLowering.h (original)
+++ llvm/trunk/include/llvm/Target/TargetFrameLowering.h Wed Jun 15 00:35:14 2016
@@ -249,12 +249,16 @@ public:
   /// Same as above, except that the 'base register' will always be RSP, not
   /// RBP on x86. This is generally used for emitting statepoint or EH tables
   /// that use offsets from RSP.
+  /// If AllowSPAdjustment is true, the returned offset is only guaranteed
+  /// to be valid with respect to the value of SP at the end of the prologue.
   /// TODO: This should really be a parameterizable choice.
-  virtual int getFrameIndexReferenceFromSP(const MachineFunction &MF, int FI,
-                                           unsigned &FrameReg) const {
+  virtual Optional<int>
+  getFrameIndexReferenceFromSP(const MachineFunction &MF, int FI,
+                               unsigned &FrameReg,
+                               bool AllowSPAdjustment) const {
     // default to calling normal version, we override this on x86 only
     llvm_unreachable("unimplemented for non-x86");
-    return 0;
+    return None;
   }
 
   /// This method determines which of the registers reported by

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp?rev=272756&r1=272755&r2=272756&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp Wed Jun 15 00:35:14 2016
@@ -302,7 +302,8 @@ int WinException::getFrameIndexOffset(in
   const TargetFrameLowering &TFI = *Asm->MF->getSubtarget().getFrameLowering();
   unsigned UnusedReg;
   if (Asm->MAI->usesWindowsCFI())
-    return TFI.getFrameIndexReferenceFromSP(*Asm->MF, FrameIndex, UnusedReg);
+    return *TFI.getFrameIndexReferenceFromSP(*Asm->MF, FrameIndex, UnusedReg,
+                                             /*AllowSPAdjustment*/ true);
   // For 32-bit, offsets should be relative to the end of the EH registration
   // node. For 64-bit, it's relative to SP at the end of the prologue.
   assert(FuncInfo.EHRegNodeEndOffset != INT_MAX);

Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=272756&r1=272755&r2=272756&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original)
+++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Wed Jun 15 00:35:14 2016
@@ -1094,9 +1094,16 @@ void PEI::replaceFrameIndices(MachineBas
                "DBG_VALUE machine instruction");
         unsigned Reg;
         MachineOperand &Offset = MI->getOperand(i + 1);
-        const unsigned refOffset =
-          TFI->getFrameIndexReferenceFromSP(Fn, MI->getOperand(i).getIndex(),
-                                            Reg);
+        int refOffset;
+        // First try to get an offset relative to SP. If that's not
+        // possible use whatever the target usually uses.
+        auto SPOffset = TFI->getFrameIndexReferenceFromSP(
+            Fn, MI->getOperand(i).getIndex(), Reg, /*AllowSPAdjustment*/ false);
+        if (SPOffset)
+          refOffset = *SPOffset;
+        else
+          refOffset = TFI->getFrameIndexReference(
+              Fn, MI->getOperand(i).getIndex(), Reg);
 
         Offset.setImm(Offset.getImm() + refOffset);
         MI->getOperand(i).ChangeToRegister(Reg, false /*isDef*/);

Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.cpp?rev=272756&r1=272755&r2=272756&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp Wed Jun 15 00:35:14 2016
@@ -1436,7 +1436,8 @@ X86FrameLowering::getPSPSlotOffsetFromSP
   // getFrameIndexReferenceFromSP has an out ref parameter for the stack
   // pointer register; pass a dummy that we ignore
   unsigned SPReg;
-  int Offset = getFrameIndexReferenceFromSP(MF, Info.PSPSymFrameIdx, SPReg);
+  int Offset = *getFrameIndexReferenceFromSP(MF, Info.PSPSymFrameIdx, SPReg,
+                                             /*AllowSPAdjustment*/ true);
   assert(Offset >= 0);
   return static_cast<unsigned>(Offset);
 }
@@ -1722,57 +1723,60 @@ int X86FrameLowering::getFrameIndexRefer
 }
 
 // Simplified from getFrameIndexReference keeping only StackPointer cases
-int X86FrameLowering::getFrameIndexReferenceFromSP(const MachineFunction &MF,
-                                                   int FI,
-                                                   unsigned &FrameReg) const {
+Optional<int>
+X86FrameLowering::getFrameIndexReferenceFromSP(const MachineFunction &MF,
+                                               int FI, unsigned &FrameReg,
+                                               bool AllowSPAdjustment) const {
   const MachineFrameInfo *MFI = MF.getFrameInfo();
   // Does not include any dynamic realign.
   const uint64_t StackSize = MFI->getStackSize();
-  {
-#ifndef NDEBUG
-    // LLVM arranges the stack as follows:
-    //   ...
-    //   ARG2
-    //   ARG1
-    //   RETADDR
-    //   PUSH RBP   <-- RBP points here
-    //   PUSH CSRs
-    //   ~~~~~~~    <-- possible stack realignment (non-win64)
-    //   ...
-    //   STACK OBJECTS
-    //   ...        <-- RSP after prologue points here
-    //   ~~~~~~~    <-- possible stack realignment (win64)
-    //
-    // if (hasVarSizedObjects()):
-    //   ...        <-- "base pointer" (ESI/RBX) points here
-    //   DYNAMIC ALLOCAS
-    //   ...        <-- RSP points here
-    //
-    // Case 1: In the simple case of no stack realignment and no dynamic
-    // allocas, both "fixed" stack objects (arguments and CSRs) are addressable
-    // with fixed offsets from RSP.
-    //
-    // Case 2: In the case of stack realignment with no dynamic allocas, fixed
-    // stack objects are addressed with RBP and regular stack objects with RSP.
-    //
-    // Case 3: In the case of dynamic allocas and stack realignment, RSP is used
-    // to address stack arguments for outgoing calls and nothing else. The "base
-    // pointer" points to local variables, and RBP points to fixed objects.
-    //
-    // In cases 2 and 3, we can only answer for non-fixed stack objects, and the
-    // answer we give is relative to the SP after the prologue, and not the
-    // SP in the middle of the function.
-
-    assert((!MFI->isFixedObjectIndex(FI) || !TRI->needsStackRealignment(MF) ||
-            STI.isTargetWin64()) &&
-           "offset from fixed object to SP is not static");
-
-    // We don't handle tail calls, and shouldn't be seeing them either.
-    int TailCallReturnAddrDelta =
-        MF.getInfo<X86MachineFunctionInfo>()->getTCReturnAddrDelta();
-    assert(!(TailCallReturnAddrDelta < 0) && "we don't handle this case!");
-#endif
-  }
+  // LLVM arranges the stack as follows:
+  //   ...
+  //   ARG2
+  //   ARG1
+  //   RETADDR
+  //   PUSH RBP   <-- RBP points here
+  //   PUSH CSRs
+  //   ~~~~~~~    <-- possible stack realignment (non-win64)
+  //   ...
+  //   STACK OBJECTS
+  //   ...        <-- RSP after prologue points here
+  //   ~~~~~~~    <-- possible stack realignment (win64)
+  //
+  // if (hasVarSizedObjects()):
+  //   ...        <-- "base pointer" (ESI/RBX) points here
+  //   DYNAMIC ALLOCAS
+  //   ...        <-- RSP points here
+  //
+  // Case 1: In the simple case of no stack realignment and no dynamic
+  // allocas, both "fixed" stack objects (arguments and CSRs) are addressable
+  // with fixed offsets from RSP.
+  //
+  // Case 2: In the case of stack realignment with no dynamic allocas, fixed
+  // stack objects are addressed with RBP and regular stack objects with RSP.
+  //
+  // Case 3: In the case of dynamic allocas and stack realignment, RSP is used
+  // to address stack arguments for outgoing calls and nothing else. The "base
+  // pointer" points to local variables, and RBP points to fixed objects.
+  //
+  // In cases 2 and 3, we can only answer for non-fixed stack objects, and the
+  // answer we give is relative to the SP after the prologue, and not the
+  // SP in the middle of the function.
+
+  if (MFI->isFixedObjectIndex(FI) && TRI->needsStackRealignment(MF) &&
+      !STI.isTargetWin64())
+    return None;
+
+  // If !hasReservedCallFrame the function might have SP adjustement in the
+  // body.  So, even though the offset is statically known, it depends on where
+  // we are in the function.
+  const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
+  if (!AllowSPAdjustment && !TFI->hasReservedCallFrame(MF))
+    return None;
+  // We don't handle tail calls, and shouldn't be seeing them either.
+  int TailCallReturnAddrDelta =
+      MF.getInfo<X86MachineFunctionInfo>()->getTCReturnAddrDelta();
+  assert(!(TailCallReturnAddrDelta < 0) && "we don't handle this case!");
 
   // Fill in FrameReg output argument.
   FrameReg = TRI->getStackRegister();

Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.h?rev=272756&r1=272755&r2=272756&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FrameLowering.h (original)
+++ llvm/trunk/lib/Target/X86/X86FrameLowering.h Wed Jun 15 00:35:14 2016
@@ -100,8 +100,10 @@ public:
   int getFrameIndexReference(const MachineFunction &MF, int FI,
                              unsigned &FrameReg) const override;
 
-  int getFrameIndexReferenceFromSP(const MachineFunction &MF, int FI,
-                                   unsigned &FrameReg) const override;
+  Optional<int>
+  getFrameIndexReferenceFromSP(const MachineFunction &MF, int FI,
+                               unsigned &FrameReg,
+                               bool AllowSPAdjustment) const override;
 
   MachineBasicBlock::iterator
   eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,

Modified: llvm/trunk/test/CodeGen/X86/deopt-bundles.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/deopt-bundles.ll?rev=272756&r1=272755&r2=272756&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/deopt-bundles.ll (original)
+++ llvm/trunk/test/CodeGen/X86/deopt-bundles.ll Wed Jun 15 00:35:14 2016
@@ -146,3 +146,16 @@ try.cont:
 }
 
 declare i32 @__CxxFrameHandler3(...)
+
+define void @f_0(i64 %n) {
+  ; CHECK-LABEL: _f_0
+  %s = alloca i64
+  %vl = alloca i64, i64 %n
+  ; Check that the stackmap does not reference %s through
+  ; SP since the offset is not static because of %vl.
+  ; STACKMAPS: Loc 3: Direct 6
+  call void @g_0(i64* %vl) [ "deopt"(i64* %s) ]
+  ret void
+}
+
+declare void @g_0(i64* %vl)




More information about the llvm-commits mailing list