summaryrefslogtreecommitdiff
path: root/compiler/GHC/CoreToStg.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/CoreToStg.hs')
-rw-r--r--compiler/GHC/CoreToStg.hs59
1 files changed, 46 insertions, 13 deletions
diff --git a/compiler/GHC/CoreToStg.hs b/compiler/GHC/CoreToStg.hs
index 8082023ae7..2193577a3d 100644
--- a/compiler/GHC/CoreToStg.hs
+++ b/compiler/GHC/CoreToStg.hs
@@ -1,4 +1,6 @@
{-# LANGUAGE CPP, DeriveFunctor #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE DataKinds #-}
--
-- (c) The GRASP/AQUA Project, Glasgow University, 1993-1998
@@ -330,10 +332,11 @@ coreToTopStgRhs dflags ccs this_mod (bndr, rhs)
; let (stg_rhs, ccs') =
mkTopStgRhs dflags this_mod ccs bndr new_rhs
+ stg_rhs' = coerceStgRhs stg_rhs
stg_arity =
- stgRhsArity stg_rhs
+ stgRhsArity stg_rhs'
- ; return (ASSERT2( arity_ok stg_arity, mk_arity_msg stg_arity) stg_rhs,
+ ; return (ASSERT2( arity_ok stg_arity, mk_arity_msg stg_arity) stg_rhs',
ccs') }
where
-- It's vital that the arity on a top-level Id matches
@@ -355,13 +358,43 @@ coreToTopStgRhs dflags ccs this_mod (bndr, rhs)
text "Id arity:" <+> ppr id_arity,
text "STG arity:" <+> ppr stg_arity]
+ -- Coerces the intermediate SgStgRhs that is used in this module to StgRhs,
+ -- panicking if any StgLams are found. mkStgRhs and mkTopStgRhs remove any
+ -- lambdas that appear in the body of a let binding, and CorePrep ensures
+ -- that no other lambdas exist, so this should never panic.
+ coerceStgRhs :: SgStgRhs -> StgRhs
+ coerceStgRhs (StgRhsCon cc con args) = StgRhsCon cc con args
+ coerceStgRhs (StgRhsClosure ext cc upd_flag args body)
+ = StgRhsClosure ext cc upd_flag args (coerceStgExpr body)
+ where
+ coerceStgExpr :: SgStgExpr -> StgExpr
+ coerceStgExpr (StgApp func args) = StgApp func args
+ coerceStgExpr (StgLit lit) = StgLit lit
+ coerceStgExpr (StgConApp con args tys) = StgConApp con args tys
+ coerceStgExpr (StgOpApp op args ty) = StgOpApp op args ty
+ coerceStgExpr (StgCase scrut bndr alt_type alts)
+ = StgCase (coerceStgExpr scrut) bndr alt_type ((fmap . mapLast) coerceStgExpr alts)
+ coerceStgExpr (StgLet ext bind expr)
+ = StgLet ext (coerceStgBinding bind) (coerceStgExpr expr)
+ coerceStgExpr (StgLetNoEscape ext bind expr)
+ = StgLetNoEscape ext (coerceStgBinding bind) (coerceStgExpr expr)
+ coerceStgExpr (StgTick tick expr) = StgTick tick (coerceStgExpr expr)
+ coerceStgExpr (XStgExpr _) = pprPanic "CoreToStg.coerceStgExpr" (text "StgLam")
+
+ coerceStgBinding :: SgStgBinding -> StgBinding
+ coerceStgBinding (StgNonRec bndr rhs) = StgNonRec bndr (coerceStgRhs rhs)
+ coerceStgBinding (StgRec binds) = StgRec $ (fmap . fmap) coerceStgRhs binds
+
+ mapLast :: (a -> b) -> (c, d, a) -> (c, d, b)
+ mapLast f (c, d, a) = (c, d, f a)
+
-- ---------------------------------------------------------------------------
-- Expressions
-- ---------------------------------------------------------------------------
coreToStgExpr
:: CoreExpr
- -> CtsM StgExpr
+ -> CtsM SgStgExpr
-- The second and third components can be derived in a simple bottom up pass, not
-- dependent on any decisions about which variables will be let-no-escaped or
@@ -399,7 +432,7 @@ coreToStgExpr expr@(Lam _ _)
let
result_expr = case nonEmpty args' of
Nothing -> body'
- Just args'' -> StgLam args'' body'
+ Just args'' -> XStgExpr $ StgLam args'' body'
return result_expr
@@ -448,7 +481,7 @@ coreToStgExpr e0@(Case scrut bndr _ alts) = do
text "STG:" $$ pprStgExpr panicStgPprOpts stg
_ -> return stg
where
- vars_alt :: (AltCon, [Var], CoreExpr) -> CtsM (AltCon, [Var], StgExpr)
+ vars_alt :: (AltCon, [Var], CoreExpr) -> CtsM (AltCon, [Var], SgStgExpr)
vars_alt (con, binders, rhs)
| DataAlt c <- con, c == unboxedUnitDataCon
= -- This case is a bit smelly.
@@ -515,7 +548,7 @@ mkStgAltType bndr alts
coreToStgApp :: Id -- Function
-> [CoreArg] -- Arguments
-> [Tickish Id] -- Debug ticks
- -> CtsM StgExpr
+ -> CtsM SgStgExpr
coreToStgApp f args ticks = do
(args', ticks') <- coreToStgArgs args
how_bound <- lookupVarCts f
@@ -624,7 +657,7 @@ coreToStgArgs (arg : args) = do -- Non-type argument
coreToStgLet
:: CoreBind -- bindings
-> CoreExpr -- body
- -> CtsM StgExpr -- new let
+ -> CtsM SgStgExpr -- new let
coreToStgLet bind body = do
(bind2, body2)
@@ -650,7 +683,7 @@ coreToStgLet bind body = do
= (binder, LetBound NestedLet (manifestArity rhs))
vars_bind :: CoreBind
- -> CtsM (StgBinding,
+ -> CtsM (SgStgBinding,
[(Id, HowBound)]) -- extension to environment
vars_bind (NonRec binder rhs) = do
@@ -671,7 +704,7 @@ coreToStgLet bind body = do
return (StgRec (binders `zip` rhss2), env_ext)
coreToStgRhs :: (Id,CoreExpr)
- -> CtsM StgRhs
+ -> CtsM SgStgRhs
coreToStgRhs (bndr, rhs) = do
new_rhs <- coreToStgExpr rhs
@@ -680,10 +713,10 @@ coreToStgRhs (bndr, rhs) = do
-- Generate a top-level RHS. Any new cost centres generated for CAFs will be
-- appended to `CollectedCCs` argument.
mkTopStgRhs :: DynFlags -> Module -> CollectedCCs
- -> Id -> StgExpr -> (StgRhs, CollectedCCs)
+ -> Id -> SgStgExpr -> (SgStgRhs, CollectedCCs)
mkTopStgRhs dflags this_mod ccs bndr rhs
- | StgLam bndrs body <- rhs
+ | XStgExpr (StgLam bndrs body) <- rhs
= -- StgLam can't have empty arguments, so not CAF
( StgRhsClosure noExtFieldSilent
dontCareCCS
@@ -732,9 +765,9 @@ mkTopStgRhs dflags this_mod ccs bndr rhs
-- Generate a non-top-level RHS. Cost-centre is always currentCCS,
-- see Note [Cost-centre initialization plan].
-mkStgRhs :: Id -> StgExpr -> StgRhs
+mkStgRhs :: Id -> SgStgExpr -> SgStgRhs
mkStgRhs bndr rhs
- | StgLam bndrs body <- rhs
+ | XStgExpr (StgLam bndrs body) <- rhs
= StgRhsClosure noExtFieldSilent
currentCCS
ReEntrant