summaryrefslogtreecommitdiff
path: root/compiler/codeGen
diff options
context:
space:
mode:
authorBen Gamari <bgamari.foss@gmail.com>2016-01-05 22:10:28 +0100
committerBen Gamari <ben@smart-cactus.org>2016-01-05 22:10:28 +0100
commitbbee3e167b79d66d4a5973ea1242e2f02c2ddf13 (patch)
tree49e1ba383a2642755ffb5812d9b5a4824dd2a115 /compiler/codeGen
parente32a6e1f4ac847272598776fd15f4a98069690e5 (diff)
downloadhaskell-bbee3e167b79d66d4a5973ea1242e2f02c2ddf13.tar.gz
StgCmmForeign: Push local register creation into code generation
The interfaces to {save,load}ThreadState were quite messy due to the need to pass in local registers (produced with draws from a unique supply) since they were used from both FCode and UniqSM. This, however, is entirely unnecessary as we already have an abstraction to capture this effect: MonadUnique. Use it. This is part of an effort to properly represent stack unwinding information for foreign calls. Test Plan: validate Reviewers: austin, simonmar Reviewed By: simonmar Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D1733
Diffstat (limited to 'compiler/codeGen')
-rw-r--r--compiler/codeGen/StgCmmForeign.hs106
-rw-r--r--compiler/codeGen/StgCmmMonad.hs6
-rw-r--r--compiler/codeGen/StgCmmUtils.hs5
3 files changed, 59 insertions, 58 deletions
diff --git a/compiler/codeGen/StgCmmForeign.hs b/compiler/codeGen/StgCmmForeign.hs
index 1dc430d06c..cbbf3b64dd 100644
--- a/compiler/codeGen/StgCmmForeign.hs
+++ b/compiler/codeGen/StgCmmForeign.hs
@@ -41,6 +41,7 @@ import ForeignCall
import DynFlags
import Maybes
import Outputable
+import UniqSupply
import BasicTypes
import Control.Monad
@@ -274,22 +275,20 @@ maybe_assign_temp e = do
emitSaveThreadState :: FCode ()
emitSaveThreadState = do
dflags <- getDynFlags
- tso <- newTemp (gcWord dflags)
- cn <- newTemp (bWord dflags)
- emit $ saveThreadState dflags tso cn
-
+ code <- saveThreadState dflags
+ emit code
--- saveThreadState must be usable from the stack layout pass, where we
--- don't have FCode. Therefore it takes LocalRegs as arguments, so
--- the caller can create these.
-saveThreadState :: DynFlags -> LocalReg -> LocalReg -> CmmAGraph
-saveThreadState dflags tso cn =
- catAGraphs [
+-- | Produce code to save the current thread state to @CurrentTSO@
+saveThreadState :: MonadUnique m => DynFlags -> m CmmAGraph
+saveThreadState dflags = do
+ tso <- newTemp (gcWord dflags)
+ close_nursery <- closeNursery dflags tso
+ pure $ catAGraphs [
-- tso = CurrentTSO;
mkAssign (CmmLocal tso) stgCurrentTSO,
-- tso->stackobj->sp = Sp;
mkStore (cmmOffset dflags (CmmLoad (cmmOffset dflags (CmmReg (CmmLocal tso)) (tso_stackobj dflags)) (bWord dflags)) (stack_SP dflags)) stgSp,
- closeNursery dflags tso cn,
+ close_nursery,
-- and save the current cost centre stack in the TSO when profiling:
if gopt Opt_SccProfilingOn dflags then
mkStore (cmmOffset dflags (CmmReg (CmmLocal tso)) (tso_CCCS dflags)) curCCS
@@ -299,14 +298,18 @@ saveThreadState dflags tso cn =
emitCloseNursery :: FCode ()
emitCloseNursery = do
dflags <- getDynFlags
- tso <- newTemp (gcWord dflags)
- cn <- newTemp (bWord dflags)
- emit $ mkAssign (CmmLocal tso) stgCurrentTSO <*>
- closeNursery dflags tso cn
+ tso <- newTemp (bWord dflags)
+ code <- closeNursery dflags tso
+ emit $ mkAssign (CmmLocal tso) stgCurrentTSO <*> code
+
+{- |
+@closeNursery dflags tso@ produces code to close the nursery.
+A local register holding the value of @CurrentTSO@ is expected for
+efficiency.
-{-
Closing the nursery corresponds to the following code:
+@
tso = CurrentTSO;
cn = CurrentNuresry;
@@ -318,15 +321,13 @@ Closing the nursery corresponds to the following code:
// Set cn->free to the next unoccupied word in the block
cn->free = Hp + WDS(1);
+@
-}
-
-closeNursery :: DynFlags -> LocalReg -> LocalReg -> CmmAGraph
-closeNursery df tso cn =
- let
- tsoreg = CmmLocal tso
- cnreg = CmmLocal cn
- in
- catAGraphs [
+closeNursery :: MonadUnique m => DynFlags -> LocalReg -> m CmmAGraph
+closeNursery df tso = do
+ let tsoreg = CmmLocal tso
+ cnreg <- CmmLocal <$> newTemp (bWord df)
+ pure $ catAGraphs [
mkAssign cnreg stgCurrentNursery,
-- CurrentNursery->free = Hp+1;
@@ -350,21 +351,16 @@ closeNursery df tso cn =
emitLoadThreadState :: FCode ()
emitLoadThreadState = do
dflags <- getDynFlags
+ code <- loadThreadState dflags
+ emit code
+
+-- | Produce code to load the current thread state from @CurrentTSO@
+loadThreadState :: MonadUnique m => DynFlags -> m CmmAGraph
+loadThreadState dflags = do
tso <- newTemp (gcWord dflags)
stack <- newTemp (gcWord dflags)
- cn <- newTemp (bWord dflags)
- bdfree <- newTemp (bWord dflags)
- bdstart <- newTemp (bWord dflags)
- emit $ loadThreadState dflags tso stack cn bdfree bdstart
-
--- loadThreadState must be usable from the stack layout pass, where we
--- don't have FCode. Therefore it takes LocalRegs as arguments, so
--- the caller can create these.
-loadThreadState :: DynFlags
- -> LocalReg -> LocalReg -> LocalReg -> LocalReg -> LocalReg
- -> CmmAGraph
-loadThreadState dflags tso stack cn bdfree bdstart =
- catAGraphs [
+ open_nursery <- openNursery dflags tso
+ pure $ catAGraphs [
-- tso = CurrentTSO;
mkAssign (CmmLocal tso) stgCurrentTSO,
-- stack = tso->stackobj;
@@ -378,7 +374,7 @@ loadThreadState dflags tso stack cn bdfree bdstart =
-- HpAlloc is assumed to be set to non-zero only by a failed
-- a heap check, see HeapStackCheck.cmm:GC_GENERIC
mkAssign hpAlloc (zeroExpr dflags),
- openNursery dflags tso cn bdfree bdstart,
+ open_nursery,
-- and load the current cost centre stack from the TSO when profiling:
if gopt Opt_SccProfilingOn dflags
then storeCurCCS
@@ -391,16 +387,17 @@ loadThreadState dflags tso stack cn bdfree bdstart =
emitOpenNursery :: FCode ()
emitOpenNursery = do
dflags <- getDynFlags
- tso <- newTemp (gcWord dflags)
- cn <- newTemp (bWord dflags)
- bdfree <- newTemp (bWord dflags)
- bdstart <- newTemp (bWord dflags)
- emit $ mkAssign (CmmLocal tso) stgCurrentTSO <*>
- openNursery dflags tso cn bdfree bdstart
+ tso <- newTemp (bWord dflags)
+ code <- openNursery dflags tso
+ emit $ mkAssign (CmmLocal tso) stgCurrentTSO <*> code
+
+{- |
+@openNursery dflags tso@ produces code to open the nursery. A local register
+holding the value of @CurrentTSO@ is expected for efficiency.
-{-
Opening the nursery corresponds to the following code:
+@
tso = CurrentTSO;
cn = CurrentNursery;
bdfree = CurrentNuresry->free;
@@ -420,23 +417,20 @@ Opening the nursery corresponds to the following code:
// Set HpLim to the end of the current nursery block (note that this block
// might be a block group, consisting of several adjacent blocks.
HpLim = bdstart + CurrentNursery->blocks*BLOCK_SIZE_W - 1;
+@
-}
+openNursery :: MonadUnique m => DynFlags -> LocalReg -> m CmmAGraph
+openNursery df tso = do
+ let tsoreg = CmmLocal tso
+ cnreg <- CmmLocal <$> newTemp (bWord df)
+ bdfreereg <- CmmLocal <$> newTemp (bWord df)
+ bdstartreg <- CmmLocal <$> newTemp (bWord df)
-openNursery :: DynFlags
- -> LocalReg -> LocalReg -> LocalReg -> LocalReg
- -> CmmAGraph
-openNursery df tso cn bdfree bdstart =
- let
- tsoreg = CmmLocal tso
- cnreg = CmmLocal cn
- bdfreereg = CmmLocal bdfree
- bdstartreg = CmmLocal bdstart
- in
-- These assignments are carefully ordered to reduce register
-- pressure and generate not completely awful code on x86. To see
-- what code we generate, look at the assembly for
-- stg_returnToStackTop in rts/StgStartup.cmm.
- catAGraphs [
+ pure $ catAGraphs [
mkAssign cnreg stgCurrentNursery,
mkAssign bdfreereg (CmmLoad (nursery_bdescr_free df cnreg) (bWord df)),
diff --git a/compiler/codeGen/StgCmmMonad.hs b/compiler/codeGen/StgCmmMonad.hs
index 6611b2944e..42033200c8 100644
--- a/compiler/codeGen/StgCmmMonad.hs
+++ b/compiler/codeGen/StgCmmMonad.hs
@@ -127,6 +127,12 @@ instance Monad FCode where
{-# INLINE thenFC #-}
{-# INLINE returnFC #-}
+instance MonadUnique FCode where
+ getUniqueSupplyM = cgs_uniqs <$> getState
+ getUniqueM = FCode $ \_ st ->
+ let (u, us') = takeUniqFromSupply (cgs_uniqs st)
+ in (# u, st { cgs_uniqs = us' } #)
+
initC :: IO CgState
initC = do { uniqs <- mkSplitUniqSupply 'c'
; return (initCgState uniqs) }
diff --git a/compiler/codeGen/StgCmmUtils.hs b/compiler/codeGen/StgCmmUtils.hs
index b4dd869039..a98ce739fd 100644
--- a/compiler/codeGen/StgCmmUtils.hs
+++ b/compiler/codeGen/StgCmmUtils.hs
@@ -63,6 +63,7 @@ import Literal
import Digraph
import Util
import Unique
+import UniqSupply (MonadUnique(..))
import DynFlags
import FastString
import Outputable
@@ -345,8 +346,8 @@ assignTemp e = do { dflags <- getDynFlags
; emitAssign (CmmLocal reg) e
; return reg }
-newTemp :: CmmType -> FCode LocalReg
-newTemp rep = do { uniq <- newUnique
+newTemp :: MonadUnique m => CmmType -> m LocalReg
+newTemp rep = do { uniq <- getUniqueM
; return (LocalReg uniq rep) }
newUnboxedTupleRegs :: Type -> FCode ([LocalReg], [ForeignHint])