[commit: ghc] ghc-8.0: PPC NCG: Implement minimal stack frame header. (7364a1d)

git at git.haskell.org git at git.haskell.org
Wed Aug 31 23:24:05 UTC 2016


Repository : ssh://git@git.haskell.org/ghc

On branch  : ghc-8.0
Link       : http://ghc.haskell.org/trac/ghc/changeset/7364a1d79ffe764a57500551370194a73259dfb6/ghc

>---------------------------------------------------------------

commit 7364a1d79ffe764a57500551370194a73259dfb6
Author: Peter Trommler <ptrommler at acm.org>
Date:   Wed Aug 31 15:18:06 2016 -0400

    PPC NCG: Implement minimal stack frame header.
    
    According to the ABI specifications a minimal stack frame consists
    of a header and a minimum size parameter save area. We reserve the
    minimal size for each ABI.
    
    On PowerPC 64-bil Linux and AIX the parameter save area can accomodate
    up to eight parameters. So calls with eight parameters and fewer
    can be done without allocating a new stack frame and deallocating
    that stack frame after the call. On AIX one additional spill slot
    is available on the stack.
    
    Code size for all nofib benchmarks is 0.3 % smaller on powerpc64.
    
    Test Plan: validate on AIX
    
    Reviewers: hvr!, erikd, austin, simonmar, bgamari
    
    Reviewed By: bgamari
    
    Subscribers: thomie
    
    Differential Revision: https://phabricator.haskell.org/D2445
    
    (cherry picked from commit 010b07aae082cb6b1f2a5db3deecc5997f6d9a6d)


>---------------------------------------------------------------

7364a1d79ffe764a57500551370194a73259dfb6
 compiler/nativeGen/PPC/CodeGen.hs |  5 +++--
 compiler/nativeGen/PPC/Instr.hs   | 30 ++++++++++++++++++++++++------
 2 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/compiler/nativeGen/PPC/CodeGen.hs b/compiler/nativeGen/PPC/CodeGen.hs
index 9bcbd18..4b9a180 100644
--- a/compiler/nativeGen/PPC/CodeGen.hs
+++ b/compiler/nativeGen/PPC/CodeGen.hs
@@ -1276,14 +1276,15 @@ genCCall' dflags gcp target dest_regs args
 
         spFormat = if target32Bit platform then II32 else II64
 
+        -- TODO: Do not create a new stack frame if delta is too large.
         move_sp_down finalStack
-               | delta > 64 =
+               | delta > stackFrameHeaderSize dflags =
                         toOL [STU spFormat sp (AddrRegImm sp (ImmInt (-delta))),
                               DELTA (-delta)]
                | otherwise = nilOL
                where delta = stackDelta finalStack
         move_sp_up finalStack
-               | delta > 64 =  -- TODO: fix-up stack back-chain
+               | delta > stackFrameHeaderSize dflags =
                         toOL [ADD sp sp (RIImm (ImmInt delta)),
                               DELTA 0]
                | otherwise = nilOL
diff --git a/compiler/nativeGen/PPC/Instr.hs b/compiler/nativeGen/PPC/Instr.hs
index b5c26ed..6baeb6c 100644
--- a/compiler/nativeGen/PPC/Instr.hs
+++ b/compiler/nativeGen/PPC/Instr.hs
@@ -15,6 +15,7 @@ module PPC.Instr (
     archWordFormat,
     RI(..),
     Instr(..),
+    stackFrameHeaderSize,
     maxSpillSlots,
     allocMoreStack,
     makeFarBranches
@@ -505,7 +506,7 @@ ppc_mkSpillInstr
 
 ppc_mkSpillInstr dflags reg delta slot
   = let platform = targetPlatform dflags
-        off      = spillSlotToOffset slot
+        off      = spillSlotToOffset dflags slot
         arch     = platformArch platform
     in
     let fmt = case targetClassOfReg platform reg of
@@ -530,7 +531,7 @@ ppc_mkLoadInstr
 
 ppc_mkLoadInstr dflags reg delta slot
   = let platform = targetPlatform dflags
-        off     = spillSlotToOffset slot
+        off      = spillSlotToOffset dflags slot
         arch     = platformArch platform
     in
     let fmt = case targetClassOfReg platform reg of
@@ -546,6 +547,22 @@ ppc_mkLoadInstr dflags reg delta slot
     in instr fmt reg (AddrRegImm sp (ImmInt (off-delta)))
 
 
+-- | The size of a minimal stackframe header including minimal
+-- parameter save area.
+stackFrameHeaderSize :: DynFlags -> Int
+stackFrameHeaderSize dflags
+  = case platformOS platform of
+      OSLinux  -> case platformArch platform of
+                             -- header + parameter save area
+        ArchPPC           -> 64 -- TODO: check ABI spec
+        ArchPPC_64 ELF_V1 -> 48 + 8 * 8
+        ArchPPC_64 ELF_V2 -> 32 + 8 * 8
+        _ -> panic "PPC.stackFrameHeaderSize: Unknown Linux"
+      OSAIX    -> 24 + 8 * 4
+      OSDarwin -> 64 -- TODO: check ABI spec
+      _ -> panic "PPC.stackFrameHeaderSize: not defined for this OS"
+     where platform = targetPlatform dflags
+
 -- | The maximum number of bytes required to spill a register. PPC32
 -- has 32-bit GPRs and 64-bit FPRs, while PPC64 has 64-bit GPRs and
 -- 64-bit FPRs. So the maximum is 8 regardless of platforms unlike
@@ -557,7 +574,8 @@ spillSlotSize = 8
 -- | The number of spill slots available without allocating more.
 maxSpillSlots :: DynFlags -> Int
 maxSpillSlots dflags
-    = ((rESERVED_C_STACK_BYTES dflags - 64) `div` spillSlotSize) - 1
+    = ((rESERVED_C_STACK_BYTES dflags - stackFrameHeaderSize dflags)
+       `div` spillSlotSize) - 1
 --     = 0 -- useful for testing allocMoreStack
 
 -- | The number of bytes that the stack pointer should be aligned
@@ -567,9 +585,9 @@ stackAlign :: Int
 stackAlign = 16
 
 -- | Convert a spill slot number to a *byte* offset, with no sign.
-spillSlotToOffset :: Int -> Int
-spillSlotToOffset slot
-   = 64 + spillSlotSize * slot
+spillSlotToOffset :: DynFlags -> Int -> Int
+spillSlotToOffset dflags slot
+   = stackFrameHeaderSize dflags + spillSlotSize * slot
 
 
 --------------------------------------------------------------------------------



More information about the ghc-commits mailing list