{-# LANGUAGE CPP, DeriveFunctor #-}
module CoreToStg ( coreToStg ) where
#include "HsVersions.h"
import GhcPrelude
import CoreSyn
import CoreUtils ( exprType, findDefault, isJoinBind
, exprIsTickedString_maybe )
import CoreArity ( manifestArity )
import StgSyn
import Type
import RepType
import TyCon
import MkId ( coercionTokenId )
import Id
import IdInfo
import DataCon
import CostCentre
import VarEnv
import Module
import Name ( isExternalName, nameOccName, nameModule_maybe )
import OccName ( occNameFS )
import BasicTypes ( Arity )
import TysWiredIn ( unboxedUnitDataCon, unitDataConId )
import Literal
import Outputable
import MonadUtils
import FastString
import Util
import DynFlags
import ForeignCall
import Demand ( isUsedOnce )
import PrimOp ( PrimCall(..), primOpWrapperId )
import SrcLoc ( mkGeneralSrcSpan )
import Data.List.NonEmpty (nonEmpty, toList)
import Data.Maybe (fromMaybe)
import Control.Monad (ap)
coreToStg :: DynFlags -> Module -> CoreProgram
-> ([StgTopBinding], CollectedCCs)
coreToStg :: DynFlags
-> Module -> CoreProgram -> ([StgTopBinding], CollectedCCs)
coreToStg DynFlags
dflags Module
this_mod CoreProgram
pgm
= ([StgTopBinding]
pgm', CollectedCCs
final_ccs)
where
(IdEnv HowBound
_, ([CostCentre]
local_ccs, [CostCentreStack]
local_cc_stacks), [StgTopBinding]
pgm')
= DynFlags
-> Module
-> IdEnv HowBound
-> CollectedCCs
-> CoreProgram
-> (IdEnv HowBound, CollectedCCs, [StgTopBinding])
coreTopBindsToStg DynFlags
dflags Module
this_mod IdEnv HowBound
forall a. VarEnv a
emptyVarEnv CollectedCCs
emptyCollectedCCs CoreProgram
pgm
prof :: Bool
prof = Way
WayProf Way -> [Way] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` DynFlags -> [Way]
ways DynFlags
dflags
final_ccs :: CollectedCCs
final_ccs
| Bool
prof Bool -> Bool -> Bool
&& GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_AutoSccsOnIndividualCafs DynFlags
dflags
= ([CostCentre]
local_ccs,[CostCentreStack]
local_cc_stacks)
| Bool
prof
= (CostCentre
all_cafs_ccCostCentre -> [CostCentre] -> [CostCentre]
forall a. a -> [a] -> [a]
:[CostCentre]
local_ccs, CostCentreStack
all_cafs_ccsCostCentreStack -> [CostCentreStack] -> [CostCentreStack]
forall a. a -> [a] -> [a]
:[CostCentreStack]
local_cc_stacks)
| Bool
otherwise
= CollectedCCs
emptyCollectedCCs
(CostCentre
all_cafs_cc, CostCentreStack
all_cafs_ccs) = Module -> (CostCentre, CostCentreStack)
getAllCAFsCC Module
this_mod
coreTopBindsToStg
:: DynFlags
-> Module
-> IdEnv HowBound
-> CollectedCCs
-> CoreProgram
-> (IdEnv HowBound, CollectedCCs, [StgTopBinding])
coreTopBindsToStg :: DynFlags
-> Module
-> IdEnv HowBound
-> CollectedCCs
-> CoreProgram
-> (IdEnv HowBound, CollectedCCs, [StgTopBinding])
coreTopBindsToStg DynFlags
_ Module
_ IdEnv HowBound
env CollectedCCs
ccs []
= (IdEnv HowBound
env, CollectedCCs
ccs, [])
coreTopBindsToStg DynFlags
dflags Module
this_mod IdEnv HowBound
env CollectedCCs
ccs (CoreBind
b:CoreProgram
bs)
= (IdEnv HowBound
env2, CollectedCCs
ccs2, StgTopBinding
b'StgTopBinding -> [StgTopBinding] -> [StgTopBinding]
forall a. a -> [a] -> [a]
:[StgTopBinding]
bs')
where
(IdEnv HowBound
env1, CollectedCCs
ccs1, StgTopBinding
b' ) =
DynFlags
-> Module
-> IdEnv HowBound
-> CollectedCCs
-> CoreBind
-> (IdEnv HowBound, CollectedCCs, StgTopBinding)
coreTopBindToStg DynFlags
dflags Module
this_mod IdEnv HowBound
env CollectedCCs
ccs CoreBind
b
(IdEnv HowBound
env2, CollectedCCs
ccs2, [StgTopBinding]
bs') =
DynFlags
-> Module
-> IdEnv HowBound
-> CollectedCCs
-> CoreProgram
-> (IdEnv HowBound, CollectedCCs, [StgTopBinding])
coreTopBindsToStg DynFlags
dflags Module
this_mod IdEnv HowBound
env1 CollectedCCs
ccs1 CoreProgram
bs
coreTopBindToStg
:: DynFlags
-> Module
-> IdEnv HowBound
-> CollectedCCs
-> CoreBind
-> (IdEnv HowBound, CollectedCCs, StgTopBinding)
coreTopBindToStg :: DynFlags
-> Module
-> IdEnv HowBound
-> CollectedCCs
-> CoreBind
-> (IdEnv HowBound, CollectedCCs, StgTopBinding)
coreTopBindToStg DynFlags
_ Module
_ IdEnv HowBound
env CollectedCCs
ccs (NonRec CoreBndr
id Expr CoreBndr
e)
| Just ByteString
str <- Expr CoreBndr -> Maybe ByteString
exprIsTickedString_maybe Expr CoreBndr
e
= let
env' :: IdEnv HowBound
env' = IdEnv HowBound -> CoreBndr -> HowBound -> IdEnv HowBound
forall a. VarEnv a -> CoreBndr -> a -> VarEnv a
extendVarEnv IdEnv HowBound
env CoreBndr
id HowBound
how_bound
how_bound :: HowBound
how_bound = LetInfo -> Arity -> HowBound
LetBound LetInfo
TopLet Arity
0
in (IdEnv HowBound
env', CollectedCCs
ccs, CoreBndr -> ByteString -> StgTopBinding
forall (pass :: StgPass).
CoreBndr -> ByteString -> GenStgTopBinding pass
StgTopStringLit CoreBndr
id ByteString
str)
coreTopBindToStg DynFlags
dflags Module
this_mod IdEnv HowBound
env CollectedCCs
ccs (NonRec CoreBndr
id Expr CoreBndr
rhs)
= let
env' :: IdEnv HowBound
env' = IdEnv HowBound -> CoreBndr -> HowBound -> IdEnv HowBound
forall a. VarEnv a -> CoreBndr -> a -> VarEnv a
extendVarEnv IdEnv HowBound
env CoreBndr
id HowBound
how_bound
how_bound :: HowBound
how_bound = LetInfo -> Arity -> HowBound
LetBound LetInfo
TopLet (Arity -> HowBound) -> Arity -> HowBound
forall a b. (a -> b) -> a -> b
$! Expr CoreBndr -> Arity
manifestArity Expr CoreBndr
rhs
(StgRhs
stg_rhs, CollectedCCs
ccs') =
DynFlags
-> IdEnv HowBound
-> CtsM (StgRhs, CollectedCCs)
-> (StgRhs, CollectedCCs)
forall a. DynFlags -> IdEnv HowBound -> CtsM a -> a
initCts DynFlags
dflags IdEnv HowBound
env (CtsM (StgRhs, CollectedCCs) -> (StgRhs, CollectedCCs))
-> CtsM (StgRhs, CollectedCCs) -> (StgRhs, CollectedCCs)
forall a b. (a -> b) -> a -> b
$
DynFlags
-> CollectedCCs
-> Module
-> (CoreBndr, Expr CoreBndr)
-> CtsM (StgRhs, CollectedCCs)
coreToTopStgRhs DynFlags
dflags CollectedCCs
ccs Module
this_mod (CoreBndr
id,Expr CoreBndr
rhs)
bind :: StgTopBinding
bind = GenStgBinding 'Vanilla -> StgTopBinding
forall (pass :: StgPass).
GenStgBinding pass -> GenStgTopBinding pass
StgTopLifted (GenStgBinding 'Vanilla -> StgTopBinding)
-> GenStgBinding 'Vanilla -> StgTopBinding
forall a b. (a -> b) -> a -> b
$ BinderP 'Vanilla -> StgRhs -> GenStgBinding 'Vanilla
forall (pass :: StgPass).
BinderP pass -> GenStgRhs pass -> GenStgBinding pass
StgNonRec CoreBndr
BinderP 'Vanilla
id StgRhs
stg_rhs
in
DynFlags
-> CoreBndr
-> StgTopBinding
-> SDoc
-> (IdEnv HowBound, CollectedCCs, StgTopBinding)
-> (IdEnv HowBound, CollectedCCs, StgTopBinding)
forall a. DynFlags -> CoreBndr -> StgTopBinding -> SDoc -> a -> a
assertConsistentCafInfo DynFlags
dflags CoreBndr
id StgTopBinding
bind (StgTopBinding -> SDoc
forall a. Outputable a => a -> SDoc
ppr StgTopBinding
bind)
(IdEnv HowBound
env', CollectedCCs
ccs', StgTopBinding
bind)
coreTopBindToStg DynFlags
dflags Module
this_mod IdEnv HowBound
env CollectedCCs
ccs (Rec [(CoreBndr, Expr CoreBndr)]
pairs)
= ASSERT( not (null pairs) )
let
binders :: [CoreBndr]
binders = ((CoreBndr, Expr CoreBndr) -> CoreBndr)
-> [(CoreBndr, Expr CoreBndr)] -> [CoreBndr]
forall a b. (a -> b) -> [a] -> [b]
map (CoreBndr, Expr CoreBndr) -> CoreBndr
forall a b. (a, b) -> a
fst [(CoreBndr, Expr CoreBndr)]
pairs
extra_env' :: [(CoreBndr, HowBound)]
extra_env' = [ (CoreBndr
b, LetInfo -> Arity -> HowBound
LetBound LetInfo
TopLet (Arity -> HowBound) -> Arity -> HowBound
forall a b. (a -> b) -> a -> b
$! Expr CoreBndr -> Arity
manifestArity Expr CoreBndr
rhs)
| (CoreBndr
b, Expr CoreBndr
rhs) <- [(CoreBndr, Expr CoreBndr)]
pairs ]
env' :: IdEnv HowBound
env' = IdEnv HowBound -> [(CoreBndr, HowBound)] -> IdEnv HowBound
forall a. VarEnv a -> [(CoreBndr, a)] -> VarEnv a
extendVarEnvList IdEnv HowBound
env [(CoreBndr, HowBound)]
extra_env'
(CollectedCCs
ccs', [StgRhs]
stg_rhss)
= DynFlags
-> IdEnv HowBound
-> CtsM (CollectedCCs, [StgRhs])
-> (CollectedCCs, [StgRhs])
forall a. DynFlags -> IdEnv HowBound -> CtsM a -> a
initCts DynFlags
dflags IdEnv HowBound
env' (CtsM (CollectedCCs, [StgRhs]) -> (CollectedCCs, [StgRhs]))
-> CtsM (CollectedCCs, [StgRhs]) -> (CollectedCCs, [StgRhs])
forall a b. (a -> b) -> a -> b
$ do
(CollectedCCs
-> (CoreBndr, Expr CoreBndr) -> CtsM (CollectedCCs, StgRhs))
-> CollectedCCs
-> [(CoreBndr, Expr CoreBndr)]
-> CtsM (CollectedCCs, [StgRhs])
forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM (\CollectedCCs
ccs (CoreBndr, Expr CoreBndr)
rhs -> do
(StgRhs
rhs', CollectedCCs
ccs') <-
DynFlags
-> CollectedCCs
-> Module
-> (CoreBndr, Expr CoreBndr)
-> CtsM (StgRhs, CollectedCCs)
coreToTopStgRhs DynFlags
dflags CollectedCCs
ccs Module
this_mod (CoreBndr, Expr CoreBndr)
rhs
(CollectedCCs, StgRhs) -> CtsM (CollectedCCs, StgRhs)
forall (m :: * -> *) a. Monad m => a -> m a
return (CollectedCCs
ccs', StgRhs
rhs'))
CollectedCCs
ccs
[(CoreBndr, Expr CoreBndr)]
pairs
bind :: StgTopBinding
bind = GenStgBinding 'Vanilla -> StgTopBinding
forall (pass :: StgPass).
GenStgBinding pass -> GenStgTopBinding pass
StgTopLifted (GenStgBinding 'Vanilla -> StgTopBinding)
-> GenStgBinding 'Vanilla -> StgTopBinding
forall a b. (a -> b) -> a -> b
$ [(BinderP 'Vanilla, StgRhs)] -> GenStgBinding 'Vanilla
forall (pass :: StgPass).
[(BinderP pass, GenStgRhs pass)] -> GenStgBinding pass
StgRec ([CoreBndr] -> [StgRhs] -> [(CoreBndr, StgRhs)]
forall a b. [a] -> [b] -> [(a, b)]
zip [CoreBndr]
binders [StgRhs]
stg_rhss)
in
DynFlags
-> CoreBndr
-> StgTopBinding
-> SDoc
-> (IdEnv HowBound, CollectedCCs, StgTopBinding)
-> (IdEnv HowBound, CollectedCCs, StgTopBinding)
forall a. DynFlags -> CoreBndr -> StgTopBinding -> SDoc -> a -> a
assertConsistentCafInfo DynFlags
dflags ([CoreBndr] -> CoreBndr
forall a. [a] -> a
head [CoreBndr]
binders) StgTopBinding
bind ([CoreBndr] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [CoreBndr]
binders)
(IdEnv HowBound
env', CollectedCCs
ccs', StgTopBinding
bind)
assertConsistentCafInfo :: DynFlags -> Id -> StgTopBinding -> SDoc -> a -> a
assertConsistentCafInfo :: DynFlags -> CoreBndr -> StgTopBinding -> SDoc -> a -> a
assertConsistentCafInfo DynFlags
dflags CoreBndr
id StgTopBinding
bind SDoc
err_doc a
result
| GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_DoStgLinting DynFlags
dflags Bool -> Bool -> Bool
|| Bool
debugIsOn
, Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ CoreBndr -> StgTopBinding -> Bool
consistentCafInfo CoreBndr
id StgTopBinding
bind = String -> SDoc -> a
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"assertConsistentCafInfo" SDoc
err_doc
| Bool
otherwise = a
result
consistentCafInfo :: Id -> StgTopBinding -> Bool
consistentCafInfo :: CoreBndr -> StgTopBinding -> Bool
consistentCafInfo CoreBndr
id StgTopBinding
bind
= WARN( not (exact || is_sat_thing) , ppr id <+> ppr id_marked_caffy <+> ppr binding_is_caffy )
Bool
safe
where
safe :: Bool
safe = Bool
id_marked_caffy Bool -> Bool -> Bool
|| Bool -> Bool
not Bool
binding_is_caffy
exact :: Bool
exact = Bool
id_marked_caffy Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
binding_is_caffy
id_marked_caffy :: Bool
id_marked_caffy = CafInfo -> Bool
mayHaveCafRefs (CoreBndr -> CafInfo
idCafInfo CoreBndr
id)
binding_is_caffy :: Bool
binding_is_caffy = StgTopBinding -> Bool
forall (pass :: StgPass). GenStgTopBinding pass -> Bool
topStgBindHasCafRefs StgTopBinding
bind
is_sat_thing :: Bool
is_sat_thing = OccName -> FastString
occNameFS (Name -> OccName
nameOccName (CoreBndr -> Name
idName CoreBndr
id)) FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== String -> FastString
fsLit String
"sat"
coreToTopStgRhs
:: DynFlags
-> CollectedCCs
-> Module
-> (Id,CoreExpr)
-> CtsM (StgRhs, CollectedCCs)
coreToTopStgRhs :: DynFlags
-> CollectedCCs
-> Module
-> (CoreBndr, Expr CoreBndr)
-> CtsM (StgRhs, CollectedCCs)
coreToTopStgRhs DynFlags
dflags CollectedCCs
ccs Module
this_mod (CoreBndr
bndr, Expr CoreBndr
rhs)
= do { StgExpr
new_rhs <- Expr CoreBndr -> CtsM StgExpr
coreToStgExpr Expr CoreBndr
rhs
; let (StgRhs
stg_rhs, CollectedCCs
ccs') =
DynFlags
-> Module
-> CollectedCCs
-> CoreBndr
-> StgExpr
-> (StgRhs, CollectedCCs)
mkTopStgRhs DynFlags
dflags Module
this_mod CollectedCCs
ccs CoreBndr
bndr StgExpr
new_rhs
stg_arity :: Arity
stg_arity =
StgRhs -> Arity
stgRhsArity StgRhs
stg_rhs
; (StgRhs, CollectedCCs) -> CtsM (StgRhs, CollectedCCs)
forall (m :: * -> *) a. Monad m => a -> m a
return (ASSERT2( arity_ok stg_arity, mk_arity_msg stg_arity) stg_rhs,
CollectedCCs
ccs') }
where
arity_ok :: Arity -> Bool
arity_ok Arity
stg_arity
| Name -> Bool
isExternalName (CoreBndr -> Name
idName CoreBndr
bndr) = Arity
id_arity Arity -> Arity -> Bool
forall a. Eq a => a -> a -> Bool
== Arity
stg_arity
| Bool
otherwise = Bool
True
id_arity :: Arity
id_arity = CoreBndr -> Arity
idArity CoreBndr
bndr
mk_arity_msg :: a -> SDoc
mk_arity_msg a
stg_arity
= [SDoc] -> SDoc
vcat [CoreBndr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreBndr
bndr,
String -> SDoc
text String
"Id arity:" SDoc -> SDoc -> SDoc
<+> Arity -> SDoc
forall a. Outputable a => a -> SDoc
ppr Arity
id_arity,
String -> SDoc
text String
"STG arity:" SDoc -> SDoc -> SDoc
<+> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
stg_arity]
coreToStgExpr
:: CoreExpr
-> CtsM StgExpr
coreToStgExpr :: Expr CoreBndr -> CtsM StgExpr
coreToStgExpr (Lit (LitNumber LitNumType
LitNumInteger Integer
_ Type
_)) = String -> CtsM StgExpr
forall a. String -> a
panic String
"coreToStgExpr: LitInteger"
coreToStgExpr (Lit (LitNumber LitNumType
LitNumNatural Integer
_ Type
_)) = String -> CtsM StgExpr
forall a. String -> a
panic String
"coreToStgExpr: LitNatural"
coreToStgExpr (Lit Literal
l) = StgExpr -> CtsM StgExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (Literal -> StgExpr
forall (pass :: StgPass). Literal -> GenStgExpr pass
StgLit Literal
l)
coreToStgExpr (App (Lit Literal
LitRubbish) Expr CoreBndr
_some_unlifted_type)
= Expr CoreBndr -> CtsM StgExpr
coreToStgExpr (CoreBndr -> Expr CoreBndr
forall b. CoreBndr -> Expr b
Var CoreBndr
unitDataConId)
coreToStgExpr (Var CoreBndr
v) = CoreBndr -> [Expr CoreBndr] -> [Tickish CoreBndr] -> CtsM StgExpr
coreToStgApp CoreBndr
v [] []
coreToStgExpr (Coercion Coercion
_)
= CoreBndr -> [Expr CoreBndr] -> [Tickish CoreBndr] -> CtsM StgExpr
coreToStgApp CoreBndr
coercionTokenId [] []
coreToStgExpr expr :: Expr CoreBndr
expr@(App Expr CoreBndr
_ Expr CoreBndr
_)
= CoreBndr -> [Expr CoreBndr] -> [Tickish CoreBndr] -> CtsM StgExpr
coreToStgApp CoreBndr
f [Expr CoreBndr]
args [Tickish CoreBndr]
ticks
where
(CoreBndr
f, [Expr CoreBndr]
args, [Tickish CoreBndr]
ticks) = Expr CoreBndr -> (CoreBndr, [Expr CoreBndr], [Tickish CoreBndr])
myCollectArgs Expr CoreBndr
expr
coreToStgExpr expr :: Expr CoreBndr
expr@(Lam CoreBndr
_ Expr CoreBndr
_)
= let
([CoreBndr]
args, Expr CoreBndr
body) = Expr CoreBndr -> ([CoreBndr], Expr CoreBndr)
myCollectBinders Expr CoreBndr
expr
args' :: [CoreBndr]
args' = [CoreBndr] -> [CoreBndr]
filterStgBinders [CoreBndr]
args
in
[(CoreBndr, HowBound)] -> CtsM StgExpr -> CtsM StgExpr
forall a. [(CoreBndr, HowBound)] -> CtsM a -> CtsM a
extendVarEnvCts [ (CoreBndr
a, HowBound
LambdaBound) | CoreBndr
a <- [CoreBndr]
args' ] (CtsM StgExpr -> CtsM StgExpr) -> CtsM StgExpr -> CtsM StgExpr
forall a b. (a -> b) -> a -> b
$ do
StgExpr
body' <- Expr CoreBndr -> CtsM StgExpr
coreToStgExpr Expr CoreBndr
body
let
result_expr :: StgExpr
result_expr = case [CoreBndr] -> Maybe (NonEmpty CoreBndr)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty [CoreBndr]
args' of
Maybe (NonEmpty CoreBndr)
Nothing -> StgExpr
body'
Just NonEmpty CoreBndr
args'' -> NonEmpty (BinderP 'Vanilla) -> StgExpr -> StgExpr
forall (pass :: StgPass).
NonEmpty (BinderP pass) -> StgExpr -> GenStgExpr pass
StgLam NonEmpty CoreBndr
NonEmpty (BinderP 'Vanilla)
args'' StgExpr
body'
StgExpr -> CtsM StgExpr
forall (m :: * -> *) a. Monad m => a -> m a
return StgExpr
result_expr
coreToStgExpr (Tick Tickish CoreBndr
tick Expr CoreBndr
expr)
= do case Tickish CoreBndr
tick of
HpcTick{} -> () -> CtsM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
ProfNote{} -> () -> CtsM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
SourceNote{} -> () -> CtsM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Breakpoint{} -> String -> CtsM ()
forall a. String -> a
panic String
"coreToStgExpr: breakpoint should not happen"
StgExpr
expr2 <- Expr CoreBndr -> CtsM StgExpr
coreToStgExpr Expr CoreBndr
expr
StgExpr -> CtsM StgExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (Tickish CoreBndr -> StgExpr -> StgExpr
forall (pass :: StgPass).
Tickish CoreBndr -> GenStgExpr pass -> GenStgExpr pass
StgTick Tickish CoreBndr
tick StgExpr
expr2)
coreToStgExpr (Cast Expr CoreBndr
expr Coercion
_)
= Expr CoreBndr -> CtsM StgExpr
coreToStgExpr Expr CoreBndr
expr
coreToStgExpr (Case Expr CoreBndr
scrut CoreBndr
_ Type
_ [])
= Expr CoreBndr -> CtsM StgExpr
coreToStgExpr Expr CoreBndr
scrut
coreToStgExpr (Case Expr CoreBndr
scrut CoreBndr
bndr Type
_ [Alt CoreBndr]
alts) = do
[(AltCon, [CoreBndr], StgExpr)]
alts2 <- [(CoreBndr, HowBound)]
-> CtsM [(AltCon, [CoreBndr], StgExpr)]
-> CtsM [(AltCon, [CoreBndr], StgExpr)]
forall a. [(CoreBndr, HowBound)] -> CtsM a -> CtsM a
extendVarEnvCts [(CoreBndr
bndr, HowBound
LambdaBound)] ((Alt CoreBndr -> CtsM (AltCon, [CoreBndr], StgExpr))
-> [Alt CoreBndr] -> CtsM [(AltCon, [CoreBndr], StgExpr)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Alt CoreBndr -> CtsM (AltCon, [CoreBndr], StgExpr)
vars_alt [Alt CoreBndr]
alts)
StgExpr
scrut2 <- Expr CoreBndr -> CtsM StgExpr
coreToStgExpr Expr CoreBndr
scrut
StgExpr -> CtsM StgExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (StgExpr
-> BinderP 'Vanilla -> AltType -> [GenStgAlt 'Vanilla] -> StgExpr
forall (pass :: StgPass).
GenStgExpr pass
-> BinderP pass -> AltType -> [GenStgAlt pass] -> GenStgExpr pass
StgCase StgExpr
scrut2 CoreBndr
BinderP 'Vanilla
bndr (CoreBndr -> [Alt CoreBndr] -> AltType
mkStgAltType CoreBndr
bndr [Alt CoreBndr]
alts) [(AltCon, [CoreBndr], StgExpr)]
[GenStgAlt 'Vanilla]
alts2)
where
vars_alt :: Alt CoreBndr -> CtsM (AltCon, [CoreBndr], StgExpr)
vars_alt (AltCon
con, [CoreBndr]
binders, Expr CoreBndr
rhs)
| DataAlt DataCon
c <- AltCon
con, DataCon
c DataCon -> DataCon -> Bool
forall a. Eq a => a -> a -> Bool
== DataCon
unboxedUnitDataCon
=
ASSERT( null binders )
do { StgExpr
rhs2 <- Expr CoreBndr -> CtsM StgExpr
coreToStgExpr Expr CoreBndr
rhs
; (AltCon, [CoreBndr], StgExpr) -> CtsM (AltCon, [CoreBndr], StgExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (AltCon
DEFAULT, [], StgExpr
rhs2) }
| Bool
otherwise
= let
binders' :: [CoreBndr]
binders' = [CoreBndr] -> [CoreBndr]
filterStgBinders [CoreBndr]
binders
in
[(CoreBndr, HowBound)]
-> CtsM (AltCon, [CoreBndr], StgExpr)
-> CtsM (AltCon, [CoreBndr], StgExpr)
forall a. [(CoreBndr, HowBound)] -> CtsM a -> CtsM a
extendVarEnvCts [(CoreBndr
b, HowBound
LambdaBound) | CoreBndr
b <- [CoreBndr]
binders'] (CtsM (AltCon, [CoreBndr], StgExpr)
-> CtsM (AltCon, [CoreBndr], StgExpr))
-> CtsM (AltCon, [CoreBndr], StgExpr)
-> CtsM (AltCon, [CoreBndr], StgExpr)
forall a b. (a -> b) -> a -> b
$ do
StgExpr
rhs2 <- Expr CoreBndr -> CtsM StgExpr
coreToStgExpr Expr CoreBndr
rhs
(AltCon, [CoreBndr], StgExpr) -> CtsM (AltCon, [CoreBndr], StgExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (AltCon
con, [CoreBndr]
binders', StgExpr
rhs2)
coreToStgExpr (Let CoreBind
bind Expr CoreBndr
body) = do
CoreBind -> Expr CoreBndr -> CtsM StgExpr
coreToStgLet CoreBind
bind Expr CoreBndr
body
coreToStgExpr Expr CoreBndr
e = String -> SDoc -> CtsM StgExpr
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"coreToStgExpr" (Expr CoreBndr -> SDoc
forall a. Outputable a => a -> SDoc
ppr Expr CoreBndr
e)
mkStgAltType :: Id -> [CoreAlt] -> AltType
mkStgAltType :: CoreBndr -> [Alt CoreBndr] -> AltType
mkStgAltType CoreBndr
bndr [Alt CoreBndr]
alts
| Type -> Bool
isUnboxedTupleType Type
bndr_ty Bool -> Bool -> Bool
|| Type -> Bool
isUnboxedSumType Type
bndr_ty
= Arity -> AltType
MultiValAlt ([PrimRep] -> Arity
forall (t :: * -> *) a. Foldable t => t a -> Arity
length [PrimRep]
prim_reps)
| Bool
otherwise
= case [PrimRep]
prim_reps of
[PrimRep
LiftedRep] -> case Type -> Maybe TyCon
tyConAppTyCon_maybe (Type -> Type
unwrapType Type
bndr_ty) of
Just TyCon
tc
| TyCon -> Bool
isAbstractTyCon TyCon
tc -> AltType
look_for_better_tycon
| TyCon -> Bool
isAlgTyCon TyCon
tc -> TyCon -> AltType
AlgAlt TyCon
tc
| Bool
otherwise -> ASSERT2( _is_poly_alt_tycon tc, ppr tc )
AltType
PolyAlt
Maybe TyCon
Nothing -> AltType
PolyAlt
[PrimRep
unlifted] -> PrimRep -> AltType
PrimAlt PrimRep
unlifted
[PrimRep]
not_unary -> Arity -> AltType
MultiValAlt ([PrimRep] -> Arity
forall (t :: * -> *) a. Foldable t => t a -> Arity
length [PrimRep]
not_unary)
where
bndr_ty :: Type
bndr_ty = CoreBndr -> Type
idType CoreBndr
bndr
prim_reps :: [PrimRep]
prim_reps = HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
typePrimRep Type
bndr_ty
_is_poly_alt_tycon :: TyCon -> Bool
_is_poly_alt_tycon TyCon
tc
= TyCon -> Bool
isFunTyCon TyCon
tc
Bool -> Bool -> Bool
|| TyCon -> Bool
isPrimTyCon TyCon
tc
Bool -> Bool -> Bool
|| TyCon -> Bool
isFamilyTyCon TyCon
tc
look_for_better_tycon :: AltType
look_for_better_tycon
| ((DataAlt DataCon
con, [CoreBndr]
_, Expr CoreBndr
_) : [Alt CoreBndr]
_) <- [Alt CoreBndr]
data_alts =
TyCon -> AltType
AlgAlt (DataCon -> TyCon
dataConTyCon DataCon
con)
| Bool
otherwise =
ASSERT(null data_alts)
AltType
PolyAlt
where
([Alt CoreBndr]
data_alts, Maybe (Expr CoreBndr)
_deflt) = [Alt CoreBndr] -> ([Alt CoreBndr], Maybe (Expr CoreBndr))
forall a b. [(AltCon, [a], b)] -> ([(AltCon, [a], b)], Maybe b)
findDefault [Alt CoreBndr]
alts
coreToStgApp :: Id
-> [CoreArg]
-> [Tickish Id]
-> CtsM StgExpr
coreToStgApp :: CoreBndr -> [Expr CoreBndr] -> [Tickish CoreBndr] -> CtsM StgExpr
coreToStgApp CoreBndr
f [Expr CoreBndr]
args [Tickish CoreBndr]
ticks = do
([StgArg]
args', [Tickish CoreBndr]
ticks') <- [Expr CoreBndr] -> CtsM ([StgArg], [Tickish CoreBndr])
coreToStgArgs [Expr CoreBndr]
args
HowBound
how_bound <- CoreBndr -> CtsM HowBound
lookupVarCts CoreBndr
f
let
n_val_args :: Arity
n_val_args = [Expr CoreBndr] -> Arity
forall b. [Arg b] -> Arity
valArgCount [Expr CoreBndr]
args
f_arity :: Arity
f_arity = CoreBndr -> HowBound -> Arity
stgArity CoreBndr
f HowBound
how_bound
saturated :: Bool
saturated = Arity
f_arity Arity -> Arity -> Bool
forall a. Ord a => a -> a -> Bool
<= Arity
n_val_args
res_ty :: Type
res_ty = Expr CoreBndr -> Type
exprType (Expr CoreBndr -> [Expr CoreBndr] -> Expr CoreBndr
forall b. Expr b -> [Expr b] -> Expr b
mkApps (CoreBndr -> Expr CoreBndr
forall b. CoreBndr -> Expr b
Var CoreBndr
f) [Expr CoreBndr]
args)
app :: GenStgExpr pass
app = case CoreBndr -> IdDetails
idDetails CoreBndr
f of
DataConWorkId DataCon
dc
| Bool
saturated -> DataCon -> [StgArg] -> [Type] -> GenStgExpr pass
forall (pass :: StgPass).
DataCon -> [StgArg] -> [Type] -> GenStgExpr pass
StgConApp DataCon
dc [StgArg]
args'
([Type] -> [Type]
dropRuntimeRepArgs ([Type] -> Maybe [Type] -> [Type]
forall a. a -> Maybe a -> a
fromMaybe [] (Type -> Maybe [Type]
tyConAppArgs_maybe Type
res_ty)))
PrimOpId PrimOp
op
| Bool
saturated -> StgOp -> [StgArg] -> Type -> GenStgExpr pass
forall (pass :: StgPass).
StgOp -> [StgArg] -> Type -> GenStgExpr pass
StgOpApp (PrimOp -> StgOp
StgPrimOp PrimOp
op) [StgArg]
args' Type
res_ty
| Bool
otherwise -> CoreBndr -> [StgArg] -> GenStgExpr pass
forall (pass :: StgPass). CoreBndr -> [StgArg] -> GenStgExpr pass
StgApp (PrimOp -> CoreBndr
primOpWrapperId PrimOp
op) [StgArg]
args'
FCallId (CCall (CCallSpec (StaticTarget SourceText
_ FastString
lbl (Just UnitId
pkgId) Bool
True)
CCallConv
PrimCallConv Safety
_))
-> ASSERT( saturated )
StgOp -> [StgArg] -> Type -> GenStgExpr pass
forall (pass :: StgPass).
StgOp -> [StgArg] -> Type -> GenStgExpr pass
StgOpApp (PrimCall -> StgOp
StgPrimCallOp (FastString -> UnitId -> PrimCall
PrimCall FastString
lbl UnitId
pkgId)) [StgArg]
args' Type
res_ty
FCallId ForeignCall
call -> ASSERT( saturated )
StgOp -> [StgArg] -> Type -> GenStgExpr pass
forall (pass :: StgPass).
StgOp -> [StgArg] -> Type -> GenStgExpr pass
StgOpApp (ForeignCall -> Type -> StgOp
StgFCallOp ForeignCall
call (CoreBndr -> Type
idType CoreBndr
f)) [StgArg]
args' Type
res_ty
TickBoxOpId {} -> String -> SDoc -> GenStgExpr pass
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"coreToStg TickBox" (SDoc -> GenStgExpr pass) -> SDoc -> GenStgExpr pass
forall a b. (a -> b) -> a -> b
$ (CoreBndr, [StgArg]) -> SDoc
forall a. Outputable a => a -> SDoc
ppr (CoreBndr
f,[StgArg]
args')
IdDetails
_other -> CoreBndr -> [StgArg] -> GenStgExpr pass
forall (pass :: StgPass). CoreBndr -> [StgArg] -> GenStgExpr pass
StgApp CoreBndr
f [StgArg]
args'
tapp :: GenStgExpr pass
tapp = (Tickish CoreBndr -> GenStgExpr pass -> GenStgExpr pass)
-> GenStgExpr pass -> [Tickish CoreBndr] -> GenStgExpr pass
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Tickish CoreBndr -> GenStgExpr pass -> GenStgExpr pass
forall (pass :: StgPass).
Tickish CoreBndr -> GenStgExpr pass -> GenStgExpr pass
StgTick GenStgExpr pass
forall (pass :: StgPass). GenStgExpr pass
app ([Tickish CoreBndr]
ticks [Tickish CoreBndr] -> [Tickish CoreBndr] -> [Tickish CoreBndr]
forall a. [a] -> [a] -> [a]
++ [Tickish CoreBndr]
ticks')
GenStgExpr Any
forall (pass :: StgPass). GenStgExpr pass
app GenStgExpr Any -> CtsM StgExpr -> CtsM StgExpr
`seq` StgExpr -> CtsM StgExpr
forall (m :: * -> *) a. Monad m => a -> m a
return StgExpr
forall (pass :: StgPass). GenStgExpr pass
tapp
coreToStgArgs :: [CoreArg] -> CtsM ([StgArg], [Tickish Id])
coreToStgArgs :: [Expr CoreBndr] -> CtsM ([StgArg], [Tickish CoreBndr])
coreToStgArgs []
= ([StgArg], [Tickish CoreBndr])
-> CtsM ([StgArg], [Tickish CoreBndr])
forall (m :: * -> *) a. Monad m => a -> m a
return ([], [])
coreToStgArgs (Type Type
_ : [Expr CoreBndr]
args) = do
([StgArg]
args', [Tickish CoreBndr]
ts) <- [Expr CoreBndr] -> CtsM ([StgArg], [Tickish CoreBndr])
coreToStgArgs [Expr CoreBndr]
args
([StgArg], [Tickish CoreBndr])
-> CtsM ([StgArg], [Tickish CoreBndr])
forall (m :: * -> *) a. Monad m => a -> m a
return ([StgArg]
args', [Tickish CoreBndr]
ts)
coreToStgArgs (Coercion Coercion
_ : [Expr CoreBndr]
args)
= do { ([StgArg]
args', [Tickish CoreBndr]
ts) <- [Expr CoreBndr] -> CtsM ([StgArg], [Tickish CoreBndr])
coreToStgArgs [Expr CoreBndr]
args
; ([StgArg], [Tickish CoreBndr])
-> CtsM ([StgArg], [Tickish CoreBndr])
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreBndr -> StgArg
StgVarArg CoreBndr
coercionTokenId StgArg -> [StgArg] -> [StgArg]
forall a. a -> [a] -> [a]
: [StgArg]
args', [Tickish CoreBndr]
ts) }
coreToStgArgs (Tick Tickish CoreBndr
t Expr CoreBndr
e : [Expr CoreBndr]
args)
= ASSERT( not (tickishIsCode t) )
do { ([StgArg]
args', [Tickish CoreBndr]
ts) <- [Expr CoreBndr] -> CtsM ([StgArg], [Tickish CoreBndr])
coreToStgArgs (Expr CoreBndr
e Expr CoreBndr -> [Expr CoreBndr] -> [Expr CoreBndr]
forall a. a -> [a] -> [a]
: [Expr CoreBndr]
args)
; ([StgArg], [Tickish CoreBndr])
-> CtsM ([StgArg], [Tickish CoreBndr])
forall (m :: * -> *) a. Monad m => a -> m a
return ([StgArg]
args', Tickish CoreBndr
tTickish CoreBndr -> [Tickish CoreBndr] -> [Tickish CoreBndr]
forall a. a -> [a] -> [a]
:[Tickish CoreBndr]
ts) }
coreToStgArgs (Expr CoreBndr
arg : [Expr CoreBndr]
args) = do
([StgArg]
stg_args, [Tickish CoreBndr]
ticks) <- [Expr CoreBndr] -> CtsM ([StgArg], [Tickish CoreBndr])
coreToStgArgs [Expr CoreBndr]
args
StgExpr
arg' <- Expr CoreBndr -> CtsM StgExpr
coreToStgExpr Expr CoreBndr
arg
let
([Tickish CoreBndr]
aticks, StgExpr
arg'') = (Tickish CoreBndr -> Bool)
-> StgExpr -> ([Tickish CoreBndr], StgExpr)
forall (p :: StgPass).
(Tickish CoreBndr -> Bool)
-> GenStgExpr p -> ([Tickish CoreBndr], GenStgExpr p)
stripStgTicksTop Tickish CoreBndr -> Bool
forall id. Tickish id -> Bool
tickishFloatable StgExpr
arg'
stg_arg :: StgArg
stg_arg = case StgExpr
arg'' of
StgApp CoreBndr
v [] -> CoreBndr -> StgArg
StgVarArg CoreBndr
v
StgConApp DataCon
con [] [Type]
_ -> CoreBndr -> StgArg
StgVarArg (DataCon -> CoreBndr
dataConWorkId DataCon
con)
StgLit Literal
lit -> Literal -> StgArg
StgLitArg Literal
lit
StgExpr
_ -> String -> SDoc -> StgArg
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"coreToStgArgs" (Expr CoreBndr -> SDoc
forall a. Outputable a => a -> SDoc
ppr Expr CoreBndr
arg)
DynFlags
dflags <- CtsM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
let
arg_rep :: [PrimRep]
arg_rep = HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
typePrimRep (Expr CoreBndr -> Type
exprType Expr CoreBndr
arg)
stg_arg_rep :: [PrimRep]
stg_arg_rep = HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
typePrimRep (StgArg -> Type
stgArgType StgArg
stg_arg)
bad_args :: Bool
bad_args = Bool -> Bool
not (DynFlags -> [PrimRep] -> [PrimRep] -> Bool
primRepsCompatible DynFlags
dflags [PrimRep]
arg_rep [PrimRep]
stg_arg_rep)
WARN( bad_args, text "Dangerous-looking argument. Probable cause: bad unsafeCoerce#" $$ ppr arg )
([StgArg], [Tickish CoreBndr])
-> CtsM ([StgArg], [Tickish CoreBndr])
forall (m :: * -> *) a. Monad m => a -> m a
return (StgArg
stg_arg StgArg -> [StgArg] -> [StgArg]
forall a. a -> [a] -> [a]
: [StgArg]
stg_args, [Tickish CoreBndr]
ticks [Tickish CoreBndr] -> [Tickish CoreBndr] -> [Tickish CoreBndr]
forall a. [a] -> [a] -> [a]
++ [Tickish CoreBndr]
aticks)
coreToStgLet
:: CoreBind
-> CoreExpr
-> CtsM StgExpr
coreToStgLet :: CoreBind -> Expr CoreBndr -> CtsM StgExpr
coreToStgLet CoreBind
bind Expr CoreBndr
body = do
(GenStgBinding 'Vanilla
bind2, StgExpr
body2)
<- do
( GenStgBinding 'Vanilla
bind2, [(CoreBndr, HowBound)]
env_ext)
<- CoreBind -> CtsM (GenStgBinding 'Vanilla, [(CoreBndr, HowBound)])
vars_bind CoreBind
bind
[(CoreBndr, HowBound)]
-> CtsM (GenStgBinding 'Vanilla, StgExpr)
-> CtsM (GenStgBinding 'Vanilla, StgExpr)
forall a. [(CoreBndr, HowBound)] -> CtsM a -> CtsM a
extendVarEnvCts [(CoreBndr, HowBound)]
env_ext (CtsM (GenStgBinding 'Vanilla, StgExpr)
-> CtsM (GenStgBinding 'Vanilla, StgExpr))
-> CtsM (GenStgBinding 'Vanilla, StgExpr)
-> CtsM (GenStgBinding 'Vanilla, StgExpr)
forall a b. (a -> b) -> a -> b
$ do
StgExpr
body2 <- Expr CoreBndr -> CtsM StgExpr
coreToStgExpr Expr CoreBndr
body
(GenStgBinding 'Vanilla, StgExpr)
-> CtsM (GenStgBinding 'Vanilla, StgExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (GenStgBinding 'Vanilla
bind2, StgExpr
body2)
let
new_let :: StgExpr
new_let | CoreBind -> Bool
isJoinBind CoreBind
bind = XLetNoEscape 'Vanilla
-> GenStgBinding 'Vanilla -> StgExpr -> StgExpr
forall (pass :: StgPass).
XLetNoEscape pass
-> GenStgBinding pass -> GenStgExpr pass -> GenStgExpr pass
StgLetNoEscape XLetNoEscape 'Vanilla
NoExtFieldSilent
noExtFieldSilent GenStgBinding 'Vanilla
bind2 StgExpr
body2
| Bool
otherwise = XLet 'Vanilla -> GenStgBinding 'Vanilla -> StgExpr -> StgExpr
forall (pass :: StgPass).
XLet pass
-> GenStgBinding pass -> GenStgExpr pass -> GenStgExpr pass
StgLet XLet 'Vanilla
NoExtFieldSilent
noExtFieldSilent GenStgBinding 'Vanilla
bind2 StgExpr
body2
StgExpr -> CtsM StgExpr
forall (m :: * -> *) a. Monad m => a -> m a
return StgExpr
new_let
where
mk_binding :: a -> Expr CoreBndr -> (a, HowBound)
mk_binding a
binder Expr CoreBndr
rhs
= (a
binder, LetInfo -> Arity -> HowBound
LetBound LetInfo
NestedLet (Expr CoreBndr -> Arity
manifestArity Expr CoreBndr
rhs))
vars_bind :: CoreBind
-> CtsM (StgBinding,
[(Id, HowBound)])
vars_bind :: CoreBind -> CtsM (GenStgBinding 'Vanilla, [(CoreBndr, HowBound)])
vars_bind (NonRec CoreBndr
binder Expr CoreBndr
rhs) = do
StgRhs
rhs2 <- (CoreBndr, Expr CoreBndr) -> CtsM StgRhs
coreToStgRhs (CoreBndr
binder,Expr CoreBndr
rhs)
let
env_ext_item :: (CoreBndr, HowBound)
env_ext_item = CoreBndr -> Expr CoreBndr -> (CoreBndr, HowBound)
forall a. a -> Expr CoreBndr -> (a, HowBound)
mk_binding CoreBndr
binder Expr CoreBndr
rhs
(GenStgBinding 'Vanilla, [(CoreBndr, HowBound)])
-> CtsM (GenStgBinding 'Vanilla, [(CoreBndr, HowBound)])
forall (m :: * -> *) a. Monad m => a -> m a
return (BinderP 'Vanilla -> StgRhs -> GenStgBinding 'Vanilla
forall (pass :: StgPass).
BinderP pass -> GenStgRhs pass -> GenStgBinding pass
StgNonRec CoreBndr
BinderP 'Vanilla
binder StgRhs
rhs2, [(CoreBndr, HowBound)
env_ext_item])
vars_bind (Rec [(CoreBndr, Expr CoreBndr)]
pairs)
= let
binders :: [CoreBndr]
binders = ((CoreBndr, Expr CoreBndr) -> CoreBndr)
-> [(CoreBndr, Expr CoreBndr)] -> [CoreBndr]
forall a b. (a -> b) -> [a] -> [b]
map (CoreBndr, Expr CoreBndr) -> CoreBndr
forall a b. (a, b) -> a
fst [(CoreBndr, Expr CoreBndr)]
pairs
env_ext :: [(CoreBndr, HowBound)]
env_ext = [ CoreBndr -> Expr CoreBndr -> (CoreBndr, HowBound)
forall a. a -> Expr CoreBndr -> (a, HowBound)
mk_binding CoreBndr
b Expr CoreBndr
rhs
| (CoreBndr
b,Expr CoreBndr
rhs) <- [(CoreBndr, Expr CoreBndr)]
pairs ]
in
[(CoreBndr, HowBound)]
-> CtsM (GenStgBinding 'Vanilla, [(CoreBndr, HowBound)])
-> CtsM (GenStgBinding 'Vanilla, [(CoreBndr, HowBound)])
forall a. [(CoreBndr, HowBound)] -> CtsM a -> CtsM a
extendVarEnvCts [(CoreBndr, HowBound)]
env_ext (CtsM (GenStgBinding 'Vanilla, [(CoreBndr, HowBound)])
-> CtsM (GenStgBinding 'Vanilla, [(CoreBndr, HowBound)]))
-> CtsM (GenStgBinding 'Vanilla, [(CoreBndr, HowBound)])
-> CtsM (GenStgBinding 'Vanilla, [(CoreBndr, HowBound)])
forall a b. (a -> b) -> a -> b
$ do
[StgRhs]
rhss2 <- ((CoreBndr, Expr CoreBndr) -> CtsM StgRhs)
-> [(CoreBndr, Expr CoreBndr)] -> CtsM [StgRhs]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (CoreBndr, Expr CoreBndr) -> CtsM StgRhs
coreToStgRhs [(CoreBndr, Expr CoreBndr)]
pairs
(GenStgBinding 'Vanilla, [(CoreBndr, HowBound)])
-> CtsM (GenStgBinding 'Vanilla, [(CoreBndr, HowBound)])
forall (m :: * -> *) a. Monad m => a -> m a
return ([(BinderP 'Vanilla, StgRhs)] -> GenStgBinding 'Vanilla
forall (pass :: StgPass).
[(BinderP pass, GenStgRhs pass)] -> GenStgBinding pass
StgRec ([CoreBndr]
binders [CoreBndr] -> [StgRhs] -> [(CoreBndr, StgRhs)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [StgRhs]
rhss2), [(CoreBndr, HowBound)]
env_ext)
coreToStgRhs :: (Id,CoreExpr)
-> CtsM StgRhs
coreToStgRhs :: (CoreBndr, Expr CoreBndr) -> CtsM StgRhs
coreToStgRhs (CoreBndr
bndr, Expr CoreBndr
rhs) = do
StgExpr
new_rhs <- Expr CoreBndr -> CtsM StgExpr
coreToStgExpr Expr CoreBndr
rhs
StgRhs -> CtsM StgRhs
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreBndr -> StgExpr -> StgRhs
mkStgRhs CoreBndr
bndr StgExpr
new_rhs)
mkTopStgRhs :: DynFlags -> Module -> CollectedCCs
-> Id -> StgExpr -> (StgRhs, CollectedCCs)
mkTopStgRhs :: DynFlags
-> Module
-> CollectedCCs
-> CoreBndr
-> StgExpr
-> (StgRhs, CollectedCCs)
mkTopStgRhs DynFlags
dflags Module
this_mod CollectedCCs
ccs CoreBndr
bndr StgExpr
rhs
| StgLam NonEmpty (BinderP 'Vanilla)
bndrs StgExpr
body <- StgExpr
rhs
=
( XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> StgExpr
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
dontCareCCS
UpdateFlag
ReEntrant
(NonEmpty CoreBndr -> [CoreBndr]
forall a. NonEmpty a -> [a]
toList NonEmpty CoreBndr
NonEmpty (BinderP 'Vanilla)
bndrs) StgExpr
body
, CollectedCCs
ccs )
| StgConApp DataCon
con [StgArg]
args [Type]
_ <- StgExpr
unticked_rhs
,
Bool -> Bool
not (DynFlags -> Module -> DataCon -> [StgArg] -> Bool
isDllConApp DynFlags
dflags Module
this_mod DataCon
con [StgArg]
args)
=
ASSERT2( not (isUnboxedTupleCon con || isUnboxedSumCon con)
, ppr bndr $$ ppr con $$ ppr args)
( CostCentreStack -> DataCon -> [StgArg] -> StgRhs
forall (pass :: StgPass).
CostCentreStack -> DataCon -> [StgArg] -> GenStgRhs pass
StgRhsCon CostCentreStack
dontCareCCS DataCon
con [StgArg]
args, CollectedCCs
ccs )
| GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_AutoSccsOnIndividualCafs DynFlags
dflags
= ( XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> StgExpr
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
caf_ccs
UpdateFlag
upd_flag [] StgExpr
rhs
, CostCentre -> CostCentreStack -> CollectedCCs -> CollectedCCs
collectCC CostCentre
caf_cc CostCentreStack
caf_ccs CollectedCCs
ccs )
| Bool
otherwise
= ( XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> StgExpr
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
all_cafs_ccs
UpdateFlag
upd_flag [] StgExpr
rhs
, CollectedCCs
ccs )
where
unticked_rhs :: StgExpr
unticked_rhs = (Tickish CoreBndr -> Bool) -> StgExpr -> StgExpr
forall (p :: StgPass).
(Tickish CoreBndr -> Bool) -> GenStgExpr p -> GenStgExpr p
stripStgTicksTopE (Bool -> Bool
not (Bool -> Bool)
-> (Tickish CoreBndr -> Bool) -> Tickish CoreBndr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tickish CoreBndr -> Bool
forall id. Tickish id -> Bool
tickishIsCode) StgExpr
rhs
upd_flag :: UpdateFlag
upd_flag | JointDmd (Str StrDmd) (Use UseDmd) -> Bool
forall s u. JointDmd (Str s) (Use u) -> Bool
isUsedOnce (CoreBndr -> JointDmd (Str StrDmd) (Use UseDmd)
idDemandInfo CoreBndr
bndr) = UpdateFlag
SingleEntry
| Bool
otherwise = UpdateFlag
Updatable
caf_cc :: CostCentre
caf_cc = CoreBndr -> Module -> CostCentre
mkAutoCC CoreBndr
bndr Module
modl
caf_ccs :: CostCentreStack
caf_ccs = CostCentre -> CostCentreStack
mkSingletonCCS CostCentre
caf_cc
modl :: Module
modl | Just Module
m <- Name -> Maybe Module
nameModule_maybe (CoreBndr -> Name
idName CoreBndr
bndr) = Module
m
| Bool
otherwise = Module
this_mod
(CostCentre
_, CostCentreStack
all_cafs_ccs) = Module -> (CostCentre, CostCentreStack)
getAllCAFsCC Module
this_mod
mkStgRhs :: Id -> StgExpr -> StgRhs
mkStgRhs :: CoreBndr -> StgExpr -> StgRhs
mkStgRhs CoreBndr
bndr StgExpr
rhs
| StgLam NonEmpty (BinderP 'Vanilla)
bndrs StgExpr
body <- StgExpr
rhs
= XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> StgExpr
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
currentCCS
UpdateFlag
ReEntrant
(NonEmpty CoreBndr -> [CoreBndr]
forall a. NonEmpty a -> [a]
toList NonEmpty CoreBndr
NonEmpty (BinderP 'Vanilla)
bndrs) StgExpr
body
| CoreBndr -> Bool
isJoinId CoreBndr
bndr
= ASSERT(idJoinArity bndr == 0)
XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> StgExpr
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
currentCCS
UpdateFlag
ReEntrant
[] StgExpr
rhs
| StgConApp DataCon
con [StgArg]
args [Type]
_ <- StgExpr
unticked_rhs
= CostCentreStack -> DataCon -> [StgArg] -> StgRhs
forall (pass :: StgPass).
CostCentreStack -> DataCon -> [StgArg] -> GenStgRhs pass
StgRhsCon CostCentreStack
currentCCS DataCon
con [StgArg]
args
| Bool
otherwise
= XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> StgExpr
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
currentCCS
UpdateFlag
upd_flag [] StgExpr
rhs
where
unticked_rhs :: StgExpr
unticked_rhs = (Tickish CoreBndr -> Bool) -> StgExpr -> StgExpr
forall (p :: StgPass).
(Tickish CoreBndr -> Bool) -> GenStgExpr p -> GenStgExpr p
stripStgTicksTopE (Bool -> Bool
not (Bool -> Bool)
-> (Tickish CoreBndr -> Bool) -> Tickish CoreBndr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tickish CoreBndr -> Bool
forall id. Tickish id -> Bool
tickishIsCode) StgExpr
rhs
upd_flag :: UpdateFlag
upd_flag | JointDmd (Str StrDmd) (Use UseDmd) -> Bool
forall s u. JointDmd (Str s) (Use u) -> Bool
isUsedOnce (CoreBndr -> JointDmd (Str StrDmd) (Use UseDmd)
idDemandInfo CoreBndr
bndr) = UpdateFlag
SingleEntry
| Bool
otherwise = UpdateFlag
Updatable
newtype CtsM a = CtsM
{ CtsM a -> DynFlags -> IdEnv HowBound -> a
unCtsM :: DynFlags
-> IdEnv HowBound
-> a
}
deriving (a -> CtsM b -> CtsM a
(a -> b) -> CtsM a -> CtsM b
(forall a b. (a -> b) -> CtsM a -> CtsM b)
-> (forall a b. a -> CtsM b -> CtsM a) -> Functor CtsM
forall a b. a -> CtsM b -> CtsM a
forall a b. (a -> b) -> CtsM a -> CtsM b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> CtsM b -> CtsM a
$c<$ :: forall a b. a -> CtsM b -> CtsM a
fmap :: (a -> b) -> CtsM a -> CtsM b
$cfmap :: forall a b. (a -> b) -> CtsM a -> CtsM b
Functor)
data HowBound
= ImportBound
| LetBound
LetInfo
Arity
| LambdaBound
deriving (HowBound -> HowBound -> Bool
(HowBound -> HowBound -> Bool)
-> (HowBound -> HowBound -> Bool) -> Eq HowBound
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HowBound -> HowBound -> Bool
$c/= :: HowBound -> HowBound -> Bool
== :: HowBound -> HowBound -> Bool
$c== :: HowBound -> HowBound -> Bool
Eq)
data LetInfo
= TopLet
| NestedLet
deriving (LetInfo -> LetInfo -> Bool
(LetInfo -> LetInfo -> Bool)
-> (LetInfo -> LetInfo -> Bool) -> Eq LetInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LetInfo -> LetInfo -> Bool
$c/= :: LetInfo -> LetInfo -> Bool
== :: LetInfo -> LetInfo -> Bool
$c== :: LetInfo -> LetInfo -> Bool
Eq)
initCts :: DynFlags -> IdEnv HowBound -> CtsM a -> a
initCts :: DynFlags -> IdEnv HowBound -> CtsM a -> a
initCts DynFlags
dflags IdEnv HowBound
env CtsM a
m = CtsM a -> DynFlags -> IdEnv HowBound -> a
forall a. CtsM a -> DynFlags -> IdEnv HowBound -> a
unCtsM CtsM a
m DynFlags
dflags IdEnv HowBound
env
{-# INLINE thenCts #-}
{-# INLINE returnCts #-}
returnCts :: a -> CtsM a
returnCts :: a -> CtsM a
returnCts a
e = (DynFlags -> IdEnv HowBound -> a) -> CtsM a
forall a. (DynFlags -> IdEnv HowBound -> a) -> CtsM a
CtsM ((DynFlags -> IdEnv HowBound -> a) -> CtsM a)
-> (DynFlags -> IdEnv HowBound -> a) -> CtsM a
forall a b. (a -> b) -> a -> b
$ \DynFlags
_ IdEnv HowBound
_ -> a
e
thenCts :: CtsM a -> (a -> CtsM b) -> CtsM b
thenCts :: CtsM a -> (a -> CtsM b) -> CtsM b
thenCts CtsM a
m a -> CtsM b
k = (DynFlags -> IdEnv HowBound -> b) -> CtsM b
forall a. (DynFlags -> IdEnv HowBound -> a) -> CtsM a
CtsM ((DynFlags -> IdEnv HowBound -> b) -> CtsM b)
-> (DynFlags -> IdEnv HowBound -> b) -> CtsM b
forall a b. (a -> b) -> a -> b
$ \DynFlags
dflags IdEnv HowBound
env
-> CtsM b -> DynFlags -> IdEnv HowBound -> b
forall a. CtsM a -> DynFlags -> IdEnv HowBound -> a
unCtsM (a -> CtsM b
k (CtsM a -> DynFlags -> IdEnv HowBound -> a
forall a. CtsM a -> DynFlags -> IdEnv HowBound -> a
unCtsM CtsM a
m DynFlags
dflags IdEnv HowBound
env)) DynFlags
dflags IdEnv HowBound
env
instance Applicative CtsM where
pure :: a -> CtsM a
pure = a -> CtsM a
forall a. a -> CtsM a
returnCts
<*> :: CtsM (a -> b) -> CtsM a -> CtsM b
(<*>) = CtsM (a -> b) -> CtsM a -> CtsM b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance Monad CtsM where
>>= :: CtsM a -> (a -> CtsM b) -> CtsM b
(>>=) = CtsM a -> (a -> CtsM b) -> CtsM b
forall a b. CtsM a -> (a -> CtsM b) -> CtsM b
thenCts
instance HasDynFlags CtsM where
getDynFlags :: CtsM DynFlags
getDynFlags = (DynFlags -> IdEnv HowBound -> DynFlags) -> CtsM DynFlags
forall a. (DynFlags -> IdEnv HowBound -> a) -> CtsM a
CtsM ((DynFlags -> IdEnv HowBound -> DynFlags) -> CtsM DynFlags)
-> (DynFlags -> IdEnv HowBound -> DynFlags) -> CtsM DynFlags
forall a b. (a -> b) -> a -> b
$ \DynFlags
dflags IdEnv HowBound
_ -> DynFlags
dflags
extendVarEnvCts :: [(Id, HowBound)] -> CtsM a -> CtsM a
extendVarEnvCts :: [(CoreBndr, HowBound)] -> CtsM a -> CtsM a
extendVarEnvCts [(CoreBndr, HowBound)]
ids_w_howbound CtsM a
expr
= (DynFlags -> IdEnv HowBound -> a) -> CtsM a
forall a. (DynFlags -> IdEnv HowBound -> a) -> CtsM a
CtsM ((DynFlags -> IdEnv HowBound -> a) -> CtsM a)
-> (DynFlags -> IdEnv HowBound -> a) -> CtsM a
forall a b. (a -> b) -> a -> b
$ \DynFlags
dflags IdEnv HowBound
env
-> CtsM a -> DynFlags -> IdEnv HowBound -> a
forall a. CtsM a -> DynFlags -> IdEnv HowBound -> a
unCtsM CtsM a
expr DynFlags
dflags (IdEnv HowBound -> [(CoreBndr, HowBound)] -> IdEnv HowBound
forall a. VarEnv a -> [(CoreBndr, a)] -> VarEnv a
extendVarEnvList IdEnv HowBound
env [(CoreBndr, HowBound)]
ids_w_howbound)
lookupVarCts :: Id -> CtsM HowBound
lookupVarCts :: CoreBndr -> CtsM HowBound
lookupVarCts CoreBndr
v = (DynFlags -> IdEnv HowBound -> HowBound) -> CtsM HowBound
forall a. (DynFlags -> IdEnv HowBound -> a) -> CtsM a
CtsM ((DynFlags -> IdEnv HowBound -> HowBound) -> CtsM HowBound)
-> (DynFlags -> IdEnv HowBound -> HowBound) -> CtsM HowBound
forall a b. (a -> b) -> a -> b
$ \DynFlags
_ IdEnv HowBound
env -> IdEnv HowBound -> CoreBndr -> HowBound
lookupBinding IdEnv HowBound
env CoreBndr
v
lookupBinding :: IdEnv HowBound -> Id -> HowBound
lookupBinding :: IdEnv HowBound -> CoreBndr -> HowBound
lookupBinding IdEnv HowBound
env CoreBndr
v = case IdEnv HowBound -> CoreBndr -> Maybe HowBound
forall a. VarEnv a -> CoreBndr -> Maybe a
lookupVarEnv IdEnv HowBound
env CoreBndr
v of
Just HowBound
xx -> HowBound
xx
Maybe HowBound
Nothing -> ASSERT2( isGlobalId v, ppr v ) ImportBound
getAllCAFsCC :: Module -> (CostCentre, CostCentreStack)
getAllCAFsCC :: Module -> (CostCentre, CostCentreStack)
getAllCAFsCC Module
this_mod =
let
span :: SrcSpan
span = FastString -> SrcSpan
mkGeneralSrcSpan (String -> FastString
mkFastString String
"<entire-module>")
all_cafs_cc :: CostCentre
all_cafs_cc = Module -> SrcSpan -> CostCentre
mkAllCafsCC Module
this_mod SrcSpan
span
all_cafs_ccs :: CostCentreStack
all_cafs_ccs = CostCentre -> CostCentreStack
mkSingletonCCS CostCentre
all_cafs_cc
in
(CostCentre
all_cafs_cc, CostCentreStack
all_cafs_ccs)
filterStgBinders :: [Var] -> [Var]
filterStgBinders :: [CoreBndr] -> [CoreBndr]
filterStgBinders [CoreBndr]
bndrs = (CoreBndr -> Bool) -> [CoreBndr] -> [CoreBndr]
forall a. (a -> Bool) -> [a] -> [a]
filter CoreBndr -> Bool
isId [CoreBndr]
bndrs
myCollectBinders :: Expr Var -> ([Var], Expr Var)
myCollectBinders :: Expr CoreBndr -> ([CoreBndr], Expr CoreBndr)
myCollectBinders Expr CoreBndr
expr
= [CoreBndr] -> Expr CoreBndr -> ([CoreBndr], Expr CoreBndr)
forall a. [a] -> Expr a -> ([a], Expr a)
go [] Expr CoreBndr
expr
where
go :: [a] -> Expr a -> ([a], Expr a)
go [a]
bs (Lam a
b Expr a
e) = [a] -> Expr a -> ([a], Expr a)
go (a
ba -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
bs) Expr a
e
go [a]
bs (Cast Expr a
e Coercion
_) = [a] -> Expr a -> ([a], Expr a)
go [a]
bs Expr a
e
go [a]
bs Expr a
e = ([a] -> [a]
forall a. [a] -> [a]
reverse [a]
bs, Expr a
e)
myCollectArgs :: CoreExpr -> (Id, [CoreArg], [Tickish Id])
myCollectArgs :: Expr CoreBndr -> (CoreBndr, [Expr CoreBndr], [Tickish CoreBndr])
myCollectArgs Expr CoreBndr
expr
= Expr CoreBndr
-> [Expr CoreBndr]
-> [Tickish CoreBndr]
-> (CoreBndr, [Expr CoreBndr], [Tickish CoreBndr])
go Expr CoreBndr
expr [] []
where
go :: Expr CoreBndr
-> [Expr CoreBndr]
-> [Tickish CoreBndr]
-> (CoreBndr, [Expr CoreBndr], [Tickish CoreBndr])
go (Var CoreBndr
v) [Expr CoreBndr]
as [Tickish CoreBndr]
ts = (CoreBndr
v, [Expr CoreBndr]
as, [Tickish CoreBndr]
ts)
go (App Expr CoreBndr
f Expr CoreBndr
a) [Expr CoreBndr]
as [Tickish CoreBndr]
ts = Expr CoreBndr
-> [Expr CoreBndr]
-> [Tickish CoreBndr]
-> (CoreBndr, [Expr CoreBndr], [Tickish CoreBndr])
go Expr CoreBndr
f (Expr CoreBndr
aExpr CoreBndr -> [Expr CoreBndr] -> [Expr CoreBndr]
forall a. a -> [a] -> [a]
:[Expr CoreBndr]
as) [Tickish CoreBndr]
ts
go (Tick Tickish CoreBndr
t Expr CoreBndr
e) [Expr CoreBndr]
as [Tickish CoreBndr]
ts = ASSERT( all isTypeArg as )
Expr CoreBndr
-> [Expr CoreBndr]
-> [Tickish CoreBndr]
-> (CoreBndr, [Expr CoreBndr], [Tickish CoreBndr])
go Expr CoreBndr
e [Expr CoreBndr]
as (Tickish CoreBndr
tTickish CoreBndr -> [Tickish CoreBndr] -> [Tickish CoreBndr]
forall a. a -> [a] -> [a]
:[Tickish CoreBndr]
ts)
go (Cast Expr CoreBndr
e Coercion
_) [Expr CoreBndr]
as [Tickish CoreBndr]
ts = Expr CoreBndr
-> [Expr CoreBndr]
-> [Tickish CoreBndr]
-> (CoreBndr, [Expr CoreBndr], [Tickish CoreBndr])
go Expr CoreBndr
e [Expr CoreBndr]
as [Tickish CoreBndr]
ts
go (Lam CoreBndr
b Expr CoreBndr
e) [Expr CoreBndr]
as [Tickish CoreBndr]
ts
| CoreBndr -> Bool
isTyVar CoreBndr
b = Expr CoreBndr
-> [Expr CoreBndr]
-> [Tickish CoreBndr]
-> (CoreBndr, [Expr CoreBndr], [Tickish CoreBndr])
go Expr CoreBndr
e [Expr CoreBndr]
as [Tickish CoreBndr]
ts
go Expr CoreBndr
_ [Expr CoreBndr]
_ [Tickish CoreBndr]
_ = String -> SDoc -> (CoreBndr, [Expr CoreBndr], [Tickish CoreBndr])
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"CoreToStg.myCollectArgs" (Expr CoreBndr -> SDoc
forall a. Outputable a => a -> SDoc
ppr Expr CoreBndr
expr)
stgArity :: Id -> HowBound -> Arity
stgArity :: CoreBndr -> HowBound -> Arity
stgArity CoreBndr
_ (LetBound LetInfo
_ Arity
arity) = Arity
arity
stgArity CoreBndr
f HowBound
ImportBound = CoreBndr -> Arity
idArity CoreBndr
f
stgArity CoreBndr
_ HowBound
LambdaBound = Arity
0