summaryrefslogtreecommitdiff
path: root/compiler/cmm/CmmLayoutStack.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/cmm/CmmLayoutStack.hs')
-rw-r--r--compiler/cmm/CmmLayoutStack.hs88
1 files changed, 40 insertions, 48 deletions
diff --git a/compiler/cmm/CmmLayoutStack.hs b/compiler/cmm/CmmLayoutStack.hs
index 4151aa0c4e..1d6c209953 100644
--- a/compiler/cmm/CmmLayoutStack.hs
+++ b/compiler/cmm/CmmLayoutStack.hs
@@ -1,8 +1,10 @@
-{-# LANGUAGE BangPatterns, CPP, RecordWildCards, GADTs #-}
+{-# LANGUAGE BangPatterns, RecordWildCards, GADTs #-}
module CmmLayoutStack (
cmmLayoutStack, setInfoTableStackMap
) where
+import GhcPrelude hiding ((<*>))
+
import StgCmmUtils ( callerSaveVolatileRegs ) -- XXX layering violation
import StgCmmForeign ( saveThreadState, loadThreadState ) -- XXX layering violation
@@ -35,11 +37,7 @@ import qualified Data.Set as Set
import Control.Monad.Fix
import Data.Array as Array
import Data.Bits
-import Data.List (nub)
-
-import Prelude hiding ((<*>))
-
-#include "HsVersions.h"
+import Data.List (nub, foldl')
{- Note [Stack Layout]
@@ -246,7 +244,7 @@ cmmLayoutStack dflags procpoints entry_args
-- We need liveness info. Dead assignments are removed later
-- by the sinking pass.
let liveness = cmmLocalLiveness dflags graph
- blocks = postorderDfs graph
+ blocks = revPostorder graph
(final_stackmaps, _final_high_sp, new_blocks) <-
mfix $ \ ~(rec_stackmaps, rec_high_sp, _new_blocks) ->
@@ -324,7 +322,7 @@ layout dflags procpoints liveness entry entry_args final_stackmaps final_sp_high
-- Sp = Sp + sp_off -- Sp adjustment goes here
-- last1 -- the last node
--
- let middle_pre = blockToList $ foldl blockSnoc middle0 middle1
+ let middle_pre = blockToList $ foldl' blockSnoc middle0 middle1
let final_blocks =
manifestSp dflags final_stackmaps stack0 sp0 final_sp_high
@@ -579,15 +577,8 @@ makeFixupBlock dflags sp0 l stack tscope assigs
| otherwise = do
tmp_lbl <- newBlockId
let sp_off = sp0 - sm_sp stack
- maybeAddUnwind block
- | debugLevel dflags > 0
- = block `blockSnoc` CmmUnwind [(Sp, Just unwind_val)]
- | otherwise
- = block
- where unwind_val = cmmOffset dflags (CmmReg spReg) (sm_sp stack)
block = blockJoin (CmmEntry tmp_lbl tscope)
- ( maybeAddSpAdj dflags sp_off
- $ maybeAddUnwind
+ ( maybeAddSpAdj dflags sp0 sp_off
$ blockFromList assigs )
(CmmBranch l)
return (tmp_lbl, [block])
@@ -853,28 +844,7 @@ manifestSp dflags stackmaps stack0 sp0 sp_high
adj_pre_sp = mapExpDeep (areaToSp dflags sp0 sp_high area_off)
adj_post_sp = mapExpDeep (areaToSp dflags (sp0 - sp_off) sp_high area_off)
- -- Add unwind pseudo-instruction at the beginning of each block to
- -- document Sp level for debugging
- add_initial_unwind block
- | debugLevel dflags > 0
- = CmmUnwind [(Sp, Just sp_unwind)] `blockCons` block
- | otherwise
- = block
- where sp_unwind = CmmRegOff spReg (sp0 - wORD_SIZE dflags)
-
- -- Add unwind pseudo-instruction right before the Sp adjustment
- -- if there is one.
- add_adj_unwind block
- | debugLevel dflags > 0
- , sp_off /= 0
- = block `blockSnoc` CmmUnwind [(Sp, Just sp_unwind)]
- | otherwise
- = block
- where sp_unwind = CmmRegOff spReg (sp0 - wORD_SIZE dflags - sp_off)
-
- final_middle = maybeAddSpAdj dflags sp_off
- . add_adj_unwind
- . add_initial_unwind
+ final_middle = maybeAddSpAdj dflags sp0 sp_off
. blockFromList
. map adj_pre_sp
. elimStackStores stack0 stackmaps area_off
@@ -893,11 +863,33 @@ getAreaOff stackmaps (Young l) =
Nothing -> pprPanic "getAreaOff" (ppr l)
-maybeAddSpAdj :: DynFlags -> ByteOff -> Block CmmNode O O -> Block CmmNode O O
-maybeAddSpAdj _ 0 block = block
-maybeAddSpAdj dflags sp_off block = block `blockSnoc` adj
+maybeAddSpAdj
+ :: DynFlags -> ByteOff -> ByteOff -> Block CmmNode O O -> Block CmmNode O O
+maybeAddSpAdj dflags sp0 sp_off block =
+ add_initial_unwind $ add_adj_unwind $ adj block
where
- adj = CmmAssign spReg (cmmOffset dflags (CmmReg spReg) sp_off)
+ adj block
+ | sp_off /= 0
+ = block `blockSnoc` CmmAssign spReg (cmmOffset dflags spExpr sp_off)
+ | otherwise = block
+ -- Add unwind pseudo-instruction at the beginning of each block to
+ -- document Sp level for debugging
+ add_initial_unwind block
+ | debugLevel dflags > 0
+ = CmmUnwind [(Sp, Just sp_unwind)] `blockCons` block
+ | otherwise
+ = block
+ where sp_unwind = CmmRegOff spReg (sp0 - wORD_SIZE dflags)
+
+ -- Add unwind pseudo-instruction right after the Sp adjustment
+ -- if there is one.
+ add_adj_unwind block
+ | debugLevel dflags > 0
+ , sp_off /= 0
+ = block `blockSnoc` CmmUnwind [(Sp, Just sp_unwind)]
+ | otherwise
+ = block
+ where sp_unwind = CmmRegOff spReg (sp0 - wORD_SIZE dflags - sp_off)
{- Note [SP old/young offsets]
@@ -920,7 +912,7 @@ arguments.
areaToSp :: DynFlags -> ByteOff -> ByteOff -> (Area -> StackLoc) -> CmmExpr -> CmmExpr
areaToSp dflags sp_old _sp_hwm area_off (CmmStackSlot area n)
- = cmmOffset dflags (CmmReg spReg) (sp_old - area_off area - n)
+ = cmmOffset dflags spExpr (sp_old - area_off area - n)
-- Replace (CmmStackSlot area n) with an offset from Sp
areaToSp dflags _ sp_hwm _ (CmmLit CmmHighStackMark)
@@ -1090,7 +1082,7 @@ insertReloads dflags stackmap live =
[ CmmAssign (CmmLocal reg)
-- This cmmOffset basically corresponds to manifesting
-- @CmmStackSlot Old sp_off@, see Note [SP old/young offsets]
- (CmmLoad (cmmOffset dflags (CmmReg spReg) (sp_off - reg_off))
+ (CmmLoad (cmmOffset dflags spExpr (sp_off - reg_off))
(localRegType reg))
| (reg, reg_off) <- stackSlotRegs stackmap
, reg `elemRegSet` live
@@ -1143,7 +1135,7 @@ lowerSafeForeignCall dflags block
-- Both 'id' and 'new_base' are KindNonPtr because they're
-- RTS-only objects and are not subject to garbage collection
id <- newTemp (bWord dflags)
- new_base <- newTemp (cmmRegType dflags (CmmGlobal BaseReg))
+ new_base <- newTemp (cmmRegType dflags baseReg)
let (caller_save, caller_load) = callerSaveVolatileRegs dflags
save_state_code <- saveThreadState dflags
load_state_code <- loadThreadState dflags
@@ -1154,7 +1146,7 @@ lowerSafeForeignCall dflags block
resume = mkMiddle (callResumeThread new_base id) <*>
-- Assign the result to BaseReg: we
-- might now have a different Capability!
- mkAssign (CmmGlobal BaseReg) (CmmReg (CmmLocal new_base)) <*>
+ mkAssign baseReg (CmmReg (CmmLocal new_base)) <*>
caller_load <*>
load_state_code
@@ -1169,7 +1161,7 @@ lowerSafeForeignCall dflags block
-- different. Hence we continue by jumping to the top stack frame,
-- not by jumping to succ.
jump = CmmCall { cml_target = entryCode dflags $
- CmmLoad (CmmReg spReg) (bWord dflags)
+ CmmLoad spExpr (bWord dflags)
, cml_cont = Just succ
, cml_args_regs = regs
, cml_args = widthInBytes (wordWidth dflags)
@@ -1199,7 +1191,7 @@ callSuspendThread dflags id intrbl =
CmmUnsafeForeignCall
(ForeignTarget (foreignLbl (fsLit "suspendThread"))
(ForeignConvention CCallConv [AddrHint, NoHint] [AddrHint] CmmMayReturn))
- [id] [CmmReg (CmmGlobal BaseReg), mkIntExpr dflags (fromEnum intrbl)]
+ [id] [baseExpr, mkIntExpr dflags (fromEnum intrbl)]
callResumeThread :: LocalReg -> LocalReg -> CmmNode O O
callResumeThread new_base id =