{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE MultiWayIf #-}
module GHC.Stg.Unarise (unarise) where
import GHC.Prelude
import GHC.Types.Basic
import GHC.Core
import GHC.Core.DataCon
import GHC.Core.TyCon
import GHC.Data.FastString (FastString, mkFastString, fsLit)
import GHC.Types.Id
import GHC.Types.Literal
import GHC.Core.Make (aBSENT_SUM_FIELD_ERROR_ID)
import GHC.Types.Id.Make (voidPrimId, voidArgId)
import GHC.Utils.Monad (mapAccumLM)
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Types.RepType
import GHC.Stg.Syntax
import GHC.Stg.Utils
import GHC.Stg.Make
import GHC.Core.Type
import GHC.Builtin.Types.Prim (intPrimTy)
import GHC.Builtin.Types
import GHC.Types.Unique.Supply
import GHC.Types.Unique
import GHC.Utils.Misc
import GHC.Types.Var.Env
import Data.Bifunctor (second)
import Data.List.NonEmpty (NonEmpty (..))
import Data.Maybe (mapMaybe)
import qualified Data.IntMap as IM
import GHC.Builtin.PrimOps
import GHC.Builtin.PrimOps.Casts
import Data.List (mapAccumL)
data UnariseEnv = UnariseEnv
{ UnariseEnv -> VarEnv UnariseVal
ue_rho :: (VarEnv UnariseVal)
, UnariseEnv -> DataCon -> [StgArg] -> Bool
ue_allow_static_conapp :: DataCon -> [StgArg] -> Bool
}
initUnariseEnv :: VarEnv UnariseVal -> (DataCon -> [StgArg] -> Bool) -> UnariseEnv
initUnariseEnv :: VarEnv UnariseVal -> (DataCon -> [StgArg] -> Bool) -> UnariseEnv
initUnariseEnv = VarEnv UnariseVal -> (DataCon -> [StgArg] -> Bool) -> UnariseEnv
UnariseEnv
data UnariseVal
= MultiVal [OutStgArg]
| UnaryVal OutStgArg
instance Outputable UnariseVal where
ppr :: UnariseVal -> SDoc
ppr (MultiVal [StgArg]
args) = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"MultiVal" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [StgArg] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [StgArg]
args
ppr (UnaryVal StgArg
arg) = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"UnaryVal" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> StgArg -> SDoc
forall a. Outputable a => a -> SDoc
ppr StgArg
arg
extendRho :: UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho :: UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
env Id
x (MultiVal [StgArg]
args)
= Bool -> UnariseEnv -> UnariseEnv
forall a. HasCallStack => Bool -> a -> a
assert ((StgArg -> Bool) -> [StgArg] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ([PrimRep] -> Bool
isNvUnaryRep ([PrimRep] -> Bool) -> (StgArg -> [PrimRep]) -> StgArg -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StgArg -> [PrimRep]
stgArgRep) [StgArg]
args)
UnariseEnv
env { ue_rho = extendVarEnv (ue_rho env) x (MultiVal args) }
extendRho UnariseEnv
env Id
x (UnaryVal StgArg
val)
= Bool -> UnariseEnv -> UnariseEnv
forall a. HasCallStack => Bool -> a -> a
assert ([PrimRep] -> Bool
isNvUnaryRep (StgArg -> [PrimRep]
stgArgRep StgArg
val))
UnariseEnv
env { ue_rho = extendVarEnv (ue_rho env) x (UnaryVal val) }
extendRhoWithoutValue :: UnariseEnv -> Id -> UnariseEnv
extendRhoWithoutValue :: UnariseEnv -> Id -> UnariseEnv
extendRhoWithoutValue UnariseEnv
env Id
x = UnariseEnv
env { ue_rho = delVarEnv (ue_rho env) x }
lookupRho :: UnariseEnv -> Id -> Maybe UnariseVal
lookupRho :: UnariseEnv -> Id -> Maybe UnariseVal
lookupRho UnariseEnv
env Id
v = VarEnv UnariseVal -> Id -> Maybe UnariseVal
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv (UnariseEnv -> VarEnv UnariseVal
ue_rho UnariseEnv
env) Id
v
unarise :: UniqSupply -> (DataCon -> [StgArg] -> Bool) -> [StgTopBinding] -> [StgTopBinding]
unarise :: UniqSupply
-> (DataCon -> [StgArg] -> Bool)
-> [StgTopBinding]
-> [StgTopBinding]
unarise UniqSupply
us DataCon -> [StgArg] -> Bool
is_dll_con_app [StgTopBinding]
binds = UniqSupply -> UniqSM [StgTopBinding] -> [StgTopBinding]
forall a. UniqSupply -> UniqSM a -> a
initUs_ UniqSupply
us ((StgTopBinding -> UniqSM StgTopBinding)
-> [StgTopBinding] -> UniqSM [StgTopBinding]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (UnariseEnv -> StgTopBinding -> UniqSM StgTopBinding
unariseTopBinding (VarEnv UnariseVal -> (DataCon -> [StgArg] -> Bool) -> UnariseEnv
initUnariseEnv VarEnv UnariseVal
forall a. VarEnv a
emptyVarEnv DataCon -> [StgArg] -> Bool
is_dll_con_app)) [StgTopBinding]
binds)
unariseTopBinding :: UnariseEnv -> StgTopBinding -> UniqSM StgTopBinding
unariseTopBinding :: UnariseEnv -> StgTopBinding -> UniqSM StgTopBinding
unariseTopBinding UnariseEnv
rho (StgTopLifted GenStgBinding 'Vanilla
bind)
= GenStgBinding 'Vanilla -> StgTopBinding
forall (pass :: StgPass).
GenStgBinding pass -> GenStgTopBinding pass
StgTopLifted (GenStgBinding 'Vanilla -> StgTopBinding)
-> UniqSM (GenStgBinding 'Vanilla) -> UniqSM StgTopBinding
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UnariseEnv
-> Bool
-> GenStgBinding 'Vanilla
-> UniqSM (GenStgBinding 'Vanilla)
unariseBinding UnariseEnv
rho Bool
True GenStgBinding 'Vanilla
bind
unariseTopBinding UnariseEnv
_ bind :: StgTopBinding
bind@StgTopStringLit{} = StgTopBinding -> UniqSM StgTopBinding
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return StgTopBinding
bind
unariseBinding :: UnariseEnv -> Bool -> StgBinding -> UniqSM StgBinding
unariseBinding :: UnariseEnv
-> Bool
-> GenStgBinding 'Vanilla
-> UniqSM (GenStgBinding 'Vanilla)
unariseBinding UnariseEnv
rho Bool
top_level (StgNonRec BinderP 'Vanilla
x GenStgRhs 'Vanilla
rhs)
= BinderP 'Vanilla -> GenStgRhs 'Vanilla -> GenStgBinding 'Vanilla
forall (pass :: StgPass).
BinderP pass -> GenStgRhs pass -> GenStgBinding pass
StgNonRec BinderP 'Vanilla
x (GenStgRhs 'Vanilla -> GenStgBinding 'Vanilla)
-> UniqSM (GenStgRhs 'Vanilla) -> UniqSM (GenStgBinding 'Vanilla)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UnariseEnv
-> Bool -> GenStgRhs 'Vanilla -> UniqSM (GenStgRhs 'Vanilla)
unariseRhs UnariseEnv
rho Bool
top_level GenStgRhs 'Vanilla
rhs
unariseBinding UnariseEnv
rho Bool
top_level (StgRec [(BinderP 'Vanilla, GenStgRhs 'Vanilla)]
xrhss)
= [(Id, GenStgRhs 'Vanilla)] -> GenStgBinding 'Vanilla
[(BinderP 'Vanilla, GenStgRhs 'Vanilla)] -> GenStgBinding 'Vanilla
forall (pass :: StgPass).
[(BinderP pass, GenStgRhs pass)] -> GenStgBinding pass
StgRec ([(Id, GenStgRhs 'Vanilla)] -> GenStgBinding 'Vanilla)
-> UniqSM [(Id, GenStgRhs 'Vanilla)]
-> UniqSM (GenStgBinding 'Vanilla)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Id, GenStgRhs 'Vanilla) -> UniqSM (Id, GenStgRhs 'Vanilla))
-> [(Id, GenStgRhs 'Vanilla)] -> UniqSM [(Id, GenStgRhs 'Vanilla)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (\(Id
x, GenStgRhs 'Vanilla
rhs) -> (Id
x,) (GenStgRhs 'Vanilla -> (Id, GenStgRhs 'Vanilla))
-> UniqSM (GenStgRhs 'Vanilla) -> UniqSM (Id, GenStgRhs 'Vanilla)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UnariseEnv
-> Bool -> GenStgRhs 'Vanilla -> UniqSM (GenStgRhs 'Vanilla)
unariseRhs UnariseEnv
rho Bool
top_level GenStgRhs 'Vanilla
rhs) [(Id, GenStgRhs 'Vanilla)]
[(BinderP 'Vanilla, GenStgRhs 'Vanilla)]
xrhss
unariseRhs :: UnariseEnv -> Bool -> StgRhs -> UniqSM StgRhs
unariseRhs :: UnariseEnv
-> Bool -> GenStgRhs 'Vanilla -> UniqSM (GenStgRhs 'Vanilla)
unariseRhs UnariseEnv
rho Bool
top_level (StgRhsClosure XRhsClosure 'Vanilla
ext CostCentreStack
ccs UpdateFlag
update_flag [BinderP 'Vanilla]
args GenStgExpr 'Vanilla
expr Type
typ)
= do (rho', args1) <- UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [Id])
unariseFunArgBinders UnariseEnv
rho [Id]
[BinderP 'Vanilla]
args
expr' <- unariseExpr rho' expr
let mk_rhs = MkStgRhs
{ rhs_args :: [Id]
rhs_args = [Id]
args1
, rhs_expr :: GenStgExpr 'Vanilla
rhs_expr = GenStgExpr 'Vanilla
expr'
, rhs_type :: Type
rhs_type = Type
typ
, rhs_is_join :: Bool
rhs_is_join = UpdateFlag
update_flag UpdateFlag -> UpdateFlag -> Bool
forall a. Eq a => a -> a -> Bool
== UpdateFlag
JumpedTo
}
if | top_level
, Just rhs_con <- mkTopStgRhsCon_maybe (ue_allow_static_conapp rho) mk_rhs
-> pure rhs_con
| not top_level
, Just rhs_con <- mkStgRhsCon_maybe mk_rhs
-> pure rhs_con
| otherwise
-> pure (StgRhsClosure ext ccs update_flag args1 expr' typ)
unariseRhs UnariseEnv
rho Bool
_top (StgRhsCon CostCentreStack
ccs DataCon
con ConstructorNumber
mu [StgTickish]
ts [StgArg]
args Type
typ)
= Bool
-> (GenStgRhs 'Vanilla -> UniqSM (GenStgRhs 'Vanilla))
-> GenStgRhs 'Vanilla
-> UniqSM (GenStgRhs 'Vanilla)
forall a. HasCallStack => Bool -> a -> a
assert (Bool -> Bool
not (DataCon -> Bool
isUnboxedTupleDataCon DataCon
con Bool -> Bool -> Bool
|| DataCon -> Bool
isUnboxedSumDataCon DataCon
con))
GenStgRhs 'Vanilla -> UniqSM (GenStgRhs 'Vanilla)
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (CostCentreStack
-> DataCon
-> ConstructorNumber
-> [StgTickish]
-> [StgArg]
-> Type
-> GenStgRhs 'Vanilla
forall (pass :: StgPass).
CostCentreStack
-> DataCon
-> ConstructorNumber
-> [StgTickish]
-> [StgArg]
-> Type
-> GenStgRhs pass
StgRhsCon CostCentreStack
ccs DataCon
con ConstructorNumber
mu [StgTickish]
ts (UnariseEnv -> [StgArg] -> [StgArg]
unariseConArgs UnariseEnv
rho [StgArg]
args) Type
typ)
unariseExpr :: UnariseEnv -> StgExpr -> UniqSM StgExpr
unariseExpr :: UnariseEnv -> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
unariseExpr UnariseEnv
rho e :: GenStgExpr 'Vanilla
e@(StgApp Id
f [])
= case UnariseEnv -> Id -> Maybe UnariseVal
lookupRho UnariseEnv
rho Id
f of
Just (MultiVal [StgArg]
args)
-> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return ([StgArg] -> GenStgExpr 'Vanilla
mkTuple [StgArg]
args)
Just (UnaryVal (StgVarArg Id
f'))
-> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> [StgArg] -> GenStgExpr 'Vanilla
forall (pass :: StgPass). Id -> [StgArg] -> GenStgExpr pass
StgApp Id
f' [])
Just (UnaryVal (StgLitArg Literal
f'))
-> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Literal -> GenStgExpr 'Vanilla
forall (pass :: StgPass). Literal -> GenStgExpr pass
StgLit Literal
f')
Maybe UnariseVal
Nothing
-> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return GenStgExpr 'Vanilla
e
unariseExpr UnariseEnv
rho e :: GenStgExpr 'Vanilla
e@(StgApp Id
f [StgArg]
args)
= GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> [StgArg] -> GenStgExpr 'Vanilla
forall (pass :: StgPass). Id -> [StgArg] -> GenStgExpr pass
StgApp Id
f' (UnariseEnv -> [StgArg] -> [StgArg]
unariseFunArgs UnariseEnv
rho [StgArg]
args))
where
f' :: Id
f' = case UnariseEnv -> Id -> Maybe UnariseVal
lookupRho UnariseEnv
rho Id
f of
Just (UnaryVal (StgVarArg Id
f')) -> Id
f'
Maybe UnariseVal
Nothing -> Id
f
Maybe UnariseVal
err -> String -> SDoc -> Id
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"unariseExpr - app2" (StgPprOpts -> GenStgExpr 'Vanilla -> SDoc
forall (pass :: StgPass).
OutputablePass pass =>
StgPprOpts -> GenStgExpr pass -> SDoc
pprStgExpr StgPprOpts
panicStgPprOpts GenStgExpr 'Vanilla
e SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ Maybe UnariseVal -> SDoc
forall a. Outputable a => a -> SDoc
ppr Maybe UnariseVal
err)
unariseExpr UnariseEnv
_ (StgLit Literal
l)
= GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Literal -> GenStgExpr 'Vanilla
forall (pass :: StgPass). Literal -> GenStgExpr pass
StgLit Literal
l)
unariseExpr UnariseEnv
rho (StgConApp DataCon
dc ConstructorNumber
n [StgArg]
args [[PrimRep]]
ty_args)
| DataCon -> Bool
isUnboxedSumDataCon DataCon
dc Bool -> Bool -> Bool
|| DataCon -> Bool
isUnboxedTupleDataCon DataCon
dc
= do
us <- UniqSM UniqSupply
forall (m :: * -> *). MonadUnique m => m UniqSupply
getUniqueSupplyM
case unariseUbxSumOrTupleArgs rho us dc args ty_args of
([StgArg]
args', Just GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
cast_wrapper)
-> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla))
-> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall a b. (a -> b) -> a -> b
$ GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
cast_wrapper ([StgArg] -> GenStgExpr 'Vanilla
mkTuple [StgArg]
args')
([StgArg]
args', Maybe (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
Nothing)
-> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla))
-> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall a b. (a -> b) -> a -> b
$ ([StgArg] -> GenStgExpr 'Vanilla
mkTuple [StgArg]
args')
| Bool
otherwise =
let args' :: [StgArg]
args' = UnariseEnv -> [StgArg] -> [StgArg]
unariseConArgs UnariseEnv
rho [StgArg]
args in
GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla))
-> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall a b. (a -> b) -> a -> b
$ (DataCon
-> ConstructorNumber
-> [StgArg]
-> [[PrimRep]]
-> GenStgExpr 'Vanilla
forall (pass :: StgPass).
DataCon
-> ConstructorNumber -> [StgArg] -> [[PrimRep]] -> GenStgExpr pass
StgConApp DataCon
dc ConstructorNumber
n [StgArg]
args' [])
unariseExpr UnariseEnv
rho (StgOpApp StgOp
op [StgArg]
args Type
ty)
= GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (StgOp -> [StgArg] -> Type -> GenStgExpr 'Vanilla
forall (pass :: StgPass).
StgOp -> [StgArg] -> Type -> GenStgExpr pass
StgOpApp StgOp
op (UnariseEnv -> [StgArg] -> [StgArg]
unariseFunArgs UnariseEnv
rho [StgArg]
args) Type
ty)
unariseExpr UnariseEnv
rho (StgCase GenStgExpr 'Vanilla
scrut BinderP 'Vanilla
bndr AltType
alt_ty [GenStgAlt 'Vanilla]
alts)
| StgApp Id
v [] <- GenStgExpr 'Vanilla
scrut
, Just (MultiVal [StgArg]
xs) <- UnariseEnv -> Id -> Maybe UnariseVal
lookupRho UnariseEnv
rho Id
v
= UnariseEnv
-> [StgArg]
-> Id
-> AltType
-> [GenStgAlt 'Vanilla]
-> UniqSM (GenStgExpr 'Vanilla)
elimCase UnariseEnv
rho [StgArg]
xs Id
BinderP 'Vanilla
bndr AltType
alt_ty [GenStgAlt 'Vanilla]
alts
| StgConApp DataCon
dc ConstructorNumber
_n [StgArg]
args [[PrimRep]]
ty_args <- GenStgExpr 'Vanilla
scrut
, DataCon -> Bool
isUnboxedSumDataCon DataCon
dc Bool -> Bool -> Bool
|| DataCon -> Bool
isUnboxedTupleDataCon DataCon
dc
= do
us <- UniqSM UniqSupply
forall (m :: * -> *). MonadUnique m => m UniqSupply
getUniqueSupplyM
case unariseUbxSumOrTupleArgs rho us dc args ty_args of
([StgArg]
args',Just GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
wrapper) -> GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
wrapper (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> UniqSM (GenStgExpr 'Vanilla) -> UniqSM (GenStgExpr 'Vanilla)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UnariseEnv
-> [StgArg]
-> Id
-> AltType
-> [GenStgAlt 'Vanilla]
-> UniqSM (GenStgExpr 'Vanilla)
elimCase UnariseEnv
rho [StgArg]
args' Id
BinderP 'Vanilla
bndr AltType
alt_ty [GenStgAlt 'Vanilla]
alts
([StgArg]
args',Maybe (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
Nothing) -> UnariseEnv
-> [StgArg]
-> Id
-> AltType
-> [GenStgAlt 'Vanilla]
-> UniqSM (GenStgExpr 'Vanilla)
elimCase UnariseEnv
rho [StgArg]
args' Id
BinderP 'Vanilla
bndr AltType
alt_ty [GenStgAlt 'Vanilla]
alts
| StgLit Literal
lit <- GenStgExpr 'Vanilla
scrut
, Just [StgArg]
args' <- Literal -> Maybe [StgArg]
unariseLiteral_maybe Literal
lit
= UnariseEnv
-> [StgArg]
-> Id
-> AltType
-> [GenStgAlt 'Vanilla]
-> UniqSM (GenStgExpr 'Vanilla)
elimCase UnariseEnv
rho [StgArg]
args' Id
BinderP 'Vanilla
bndr AltType
alt_ty [GenStgAlt 'Vanilla]
alts
| Bool
otherwise
= do scrut' <- UnariseEnv -> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
unariseExpr UnariseEnv
rho GenStgExpr 'Vanilla
scrut
alts' <- unariseAlts rho alt_ty bndr alts
return (StgCase scrut' bndr alt_ty alts')
unariseExpr UnariseEnv
rho (StgLet XLet 'Vanilla
ext GenStgBinding 'Vanilla
bind GenStgExpr 'Vanilla
e)
= XLet 'Vanilla
-> GenStgBinding 'Vanilla
-> GenStgExpr 'Vanilla
-> GenStgExpr 'Vanilla
forall (pass :: StgPass).
XLet pass
-> GenStgBinding pass -> GenStgExpr pass -> GenStgExpr pass
StgLet XLet 'Vanilla
ext (GenStgBinding 'Vanilla
-> GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> UniqSM (GenStgBinding 'Vanilla)
-> UniqSM (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UnariseEnv
-> Bool
-> GenStgBinding 'Vanilla
-> UniqSM (GenStgBinding 'Vanilla)
unariseBinding UnariseEnv
rho Bool
False GenStgBinding 'Vanilla
bind UniqSM (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> UniqSM (GenStgExpr 'Vanilla) -> UniqSM (GenStgExpr 'Vanilla)
forall a b. UniqSM (a -> b) -> UniqSM a -> UniqSM b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> UnariseEnv -> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
unariseExpr UnariseEnv
rho GenStgExpr 'Vanilla
e
unariseExpr UnariseEnv
rho (StgLetNoEscape XLetNoEscape 'Vanilla
ext GenStgBinding 'Vanilla
bind GenStgExpr 'Vanilla
e)
= XLetNoEscape 'Vanilla
-> GenStgBinding 'Vanilla
-> GenStgExpr 'Vanilla
-> GenStgExpr 'Vanilla
forall (pass :: StgPass).
XLetNoEscape pass
-> GenStgBinding pass -> GenStgExpr pass -> GenStgExpr pass
StgLetNoEscape XLetNoEscape 'Vanilla
ext (GenStgBinding 'Vanilla
-> GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> UniqSM (GenStgBinding 'Vanilla)
-> UniqSM (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UnariseEnv
-> Bool
-> GenStgBinding 'Vanilla
-> UniqSM (GenStgBinding 'Vanilla)
unariseBinding UnariseEnv
rho Bool
False GenStgBinding 'Vanilla
bind UniqSM (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> UniqSM (GenStgExpr 'Vanilla) -> UniqSM (GenStgExpr 'Vanilla)
forall a b. UniqSM (a -> b) -> UniqSM a -> UniqSM b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> UnariseEnv -> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
unariseExpr UnariseEnv
rho GenStgExpr 'Vanilla
e
unariseExpr UnariseEnv
rho (StgTick StgTickish
tick GenStgExpr 'Vanilla
e)
= StgTickish -> GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
forall (pass :: StgPass).
StgTickish -> GenStgExpr pass -> GenStgExpr pass
StgTick StgTickish
tick (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> UniqSM (GenStgExpr 'Vanilla) -> UniqSM (GenStgExpr 'Vanilla)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UnariseEnv -> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
unariseExpr UnariseEnv
rho GenStgExpr 'Vanilla
e
unariseUbxSumOrTupleArgs :: UnariseEnv -> UniqSupply -> DataCon -> [InStgArg] -> [[PrimRep]]
-> ( [OutStgArg]
, Maybe (StgExpr -> StgExpr))
unariseUbxSumOrTupleArgs :: UnariseEnv
-> UniqSupply
-> DataCon
-> [StgArg]
-> [[PrimRep]]
-> ([StgArg], Maybe (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla))
unariseUbxSumOrTupleArgs UnariseEnv
rho UniqSupply
us DataCon
dc [StgArg]
args [[PrimRep]]
ty_args
| DataCon -> Bool
isUnboxedTupleDataCon DataCon
dc
= (UnariseEnv -> [StgArg] -> [StgArg]
unariseConArgs UnariseEnv
rho [StgArg]
args, Maybe (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
forall a. Maybe a
Nothing)
| DataCon -> Bool
isUnboxedSumDataCon DataCon
dc
, let args1 :: [StgArg]
args1 = Bool -> [StgArg] -> [StgArg]
forall a. HasCallStack => Bool -> a -> a
assert ([StgArg] -> Bool
forall a. [a] -> Bool
isSingleton [StgArg]
args) (UnariseEnv -> [StgArg] -> [StgArg]
unariseConArgs UnariseEnv
rho [StgArg]
args)
= let ([StgArg]
args2, GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
cast_wrapper) = HasDebugCallStack =>
DataCon
-> [[PrimRep]]
-> [StgArg]
-> UniqSupply
-> ([StgArg], GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
DataCon
-> [[PrimRep]]
-> [StgArg]
-> UniqSupply
-> ([StgArg], GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
mkUbxSum DataCon
dc [[PrimRep]]
ty_args [StgArg]
args1 UniqSupply
us
in ([StgArg]
args2, (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> Maybe (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
forall a. a -> Maybe a
Just GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
cast_wrapper)
| Bool
otherwise
= String
-> ([StgArg], Maybe (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla))
forall a. HasCallStack => String -> a
panic String
"unariseUbxSumOrTupleArgs: Constructor not a unboxed sum or tuple"
unariseLiteral_maybe :: Literal -> Maybe [OutStgArg]
unariseLiteral_maybe :: Literal -> Maybe [StgArg]
unariseLiteral_maybe (LitRubbish TypeOrConstraint
torc Type
rep)
| [PrimRep
_] <- [PrimRep]
preps
= Maybe [StgArg]
forall a. Maybe a
Nothing
| Bool
otherwise
= [StgArg] -> Maybe [StgArg]
forall a. a -> Maybe a
Just [ Literal -> StgArg
StgLitArg (TypeOrConstraint -> Type -> Literal
LitRubbish TypeOrConstraint
torc (PrimRep -> Type
primRepToRuntimeRep PrimRep
prep))
| PrimRep
prep <- [PrimRep]
preps ]
where
preps :: [PrimRep]
preps = HasDebugCallStack => SDoc -> Type -> [PrimRep]
SDoc -> Type -> [PrimRep]
runtimeRepPrimRep (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"unariseLiteral_maybe") Type
rep
unariseLiteral_maybe Literal
_ = Maybe [StgArg]
forall a. Maybe a
Nothing
elimCase :: UnariseEnv
-> [OutStgArg]
-> InId -> AltType -> [InStgAlt] -> UniqSM OutStgExpr
elimCase :: UnariseEnv
-> [StgArg]
-> Id
-> AltType
-> [GenStgAlt 'Vanilla]
-> UniqSM (GenStgExpr 'Vanilla)
elimCase UnariseEnv
rho [StgArg]
args Id
bndr (MultiValAlt Int
_) [GenStgAlt{ alt_con :: forall (pass :: StgPass). GenStgAlt pass -> AltCon
alt_con = AltCon
_
, alt_bndrs :: forall (pass :: StgPass). GenStgAlt pass -> [BinderP pass]
alt_bndrs = [BinderP 'Vanilla]
bndrs
, alt_rhs :: forall (pass :: StgPass). GenStgAlt pass -> GenStgExpr pass
alt_rhs = GenStgExpr 'Vanilla
rhs}]
= do let rho1 :: UnariseEnv
rho1 = UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho Id
bndr ([StgArg] -> UnariseVal
MultiVal [StgArg]
args)
(rho2, rhs') <- case () of
()
_
| Id -> Bool
isUnboxedTupleBndr Id
bndr
-> (UnariseEnv, GenStgExpr 'Vanilla)
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Id] -> [StgArg] -> UnariseEnv -> UnariseEnv
mapTupleIdBinders [Id]
[BinderP 'Vanilla]
bndrs [StgArg]
args UnariseEnv
rho1, GenStgExpr 'Vanilla
rhs)
| Bool
otherwise
-> Bool
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
forall a. HasCallStack => Bool -> a -> a
assert (Id -> Bool
isUnboxedSumBndr Id
bndr) (UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla))
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
forall a b. (a -> b) -> a -> b
$
case [BinderP 'Vanilla]
bndrs of
[] -> (UnariseEnv, GenStgExpr 'Vanilla)
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (UnariseEnv
rho1, GenStgExpr 'Vanilla
rhs)
[BinderP 'Vanilla
alt_bndr] -> Id
-> [StgArg]
-> GenStgExpr 'Vanilla
-> UnariseEnv
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
mapSumIdBinders Id
BinderP 'Vanilla
alt_bndr [StgArg]
args GenStgExpr 'Vanilla
rhs UnariseEnv
rho1
[BinderP 'Vanilla]
_ -> String -> SDoc -> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"mapSumIdBinders" ([Id] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Id]
[BinderP 'Vanilla]
bndrs SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ [StgArg] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [StgArg]
args)
unariseExpr rho2 rhs'
elimCase UnariseEnv
rho args :: [StgArg]
args@(StgArg
tag_arg : [StgArg]
real_args) Id
bndr (MultiValAlt Int
_) [GenStgAlt 'Vanilla]
alts
| Id -> Bool
isUnboxedSumBndr Id
bndr
= do tag_bndr <- FastString -> Type -> UniqSM Id
mkId (String -> FastString
mkFastString String
"tag") Type
tagTy
let rho1 = UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho Id
bndr ([StgArg] -> UnariseVal
MultiVal [StgArg]
args)
scrut' = case StgArg
tag_arg of
StgVarArg Id
v -> Id -> [StgArg] -> GenStgExpr 'Vanilla
forall (pass :: StgPass). Id -> [StgArg] -> GenStgExpr pass
StgApp Id
v []
StgLitArg Literal
l -> Literal -> GenStgExpr 'Vanilla
forall (pass :: StgPass). Literal -> GenStgExpr pass
StgLit Literal
l
alts' <- unariseSumAlts rho1 real_args alts
return (StgCase scrut' tag_bndr tagAltTy alts')
elimCase UnariseEnv
_ [StgArg]
args Id
bndr AltType
alt_ty [GenStgAlt 'Vanilla]
alts
= String -> SDoc -> UniqSM (GenStgExpr 'Vanilla)
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"elimCase - unhandled case"
([StgArg] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [StgArg]
args SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
bndr SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> AltType -> SDoc
forall a. Outputable a => a -> SDoc
ppr AltType
alt_ty SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ [GenStgAlt 'Vanilla] -> SDoc
forall (pass :: StgPass).
OutputablePass pass =>
[GenStgAlt pass] -> SDoc
pprPanicAlts [GenStgAlt 'Vanilla]
alts)
unariseAlts :: UnariseEnv -> AltType -> InId -> [StgAlt] -> UniqSM [StgAlt]
unariseAlts :: UnariseEnv
-> AltType
-> Id
-> [GenStgAlt 'Vanilla]
-> UniqSM [GenStgAlt 'Vanilla]
unariseAlts UnariseEnv
rho (MultiValAlt Int
n) Id
bndr [GenStgAlt{ alt_con :: forall (pass :: StgPass). GenStgAlt pass -> AltCon
alt_con = AltCon
DEFAULT
, alt_bndrs :: forall (pass :: StgPass). GenStgAlt pass -> [BinderP pass]
alt_bndrs = []
, alt_rhs :: forall (pass :: StgPass). GenStgAlt pass -> GenStgExpr pass
alt_rhs = GenStgExpr 'Vanilla
e}]
| Id -> Bool
isUnboxedTupleBndr Id
bndr
= do (rho', ys) <- UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseConArgBinder UnariseEnv
rho Id
bndr
!e' <- unariseExpr rho' e
return [GenStgAlt (DataAlt (tupleDataCon Unboxed n)) ys e']
unariseAlts UnariseEnv
rho (MultiValAlt Int
n) Id
bndr [GenStgAlt{ alt_con :: forall (pass :: StgPass). GenStgAlt pass -> AltCon
alt_con = DataAlt DataCon
_
, alt_bndrs :: forall (pass :: StgPass). GenStgAlt pass -> [BinderP pass]
alt_bndrs = [BinderP 'Vanilla]
ys
, alt_rhs :: forall (pass :: StgPass). GenStgAlt pass -> GenStgExpr pass
alt_rhs = GenStgExpr 'Vanilla
e}]
| Id -> Bool
isUnboxedTupleBndr Id
bndr
= do (rho', ys1) <- UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [Id])
unariseConArgBinders UnariseEnv
rho [Id]
[BinderP 'Vanilla]
ys
massert (ys1 `lengthIs` n)
let rho'' = UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho' Id
bndr ([StgArg] -> UnariseVal
MultiVal ((Id -> StgArg) -> [Id] -> [StgArg]
forall a b. (a -> b) -> [a] -> [b]
map Id -> StgArg
StgVarArg [Id]
ys1))
!e' <- unariseExpr rho'' e
return [GenStgAlt (DataAlt (tupleDataCon Unboxed n)) ys1 e']
unariseAlts UnariseEnv
_ (MultiValAlt Int
_) Id
bndr [GenStgAlt 'Vanilla]
alts
| Id -> Bool
isUnboxedTupleBndr Id
bndr
= String -> SDoc -> UniqSM [GenStgAlt 'Vanilla]
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"unariseExpr: strange multi val alts" ([GenStgAlt 'Vanilla] -> SDoc
forall (pass :: StgPass).
OutputablePass pass =>
[GenStgAlt pass] -> SDoc
pprPanicAlts [GenStgAlt 'Vanilla]
alts)
unariseAlts UnariseEnv
rho (MultiValAlt Int
_) Id
bndr [GenStgAlt{ alt_con :: forall (pass :: StgPass). GenStgAlt pass -> AltCon
alt_con = AltCon
DEFAULT
, alt_bndrs :: forall (pass :: StgPass). GenStgAlt pass -> [BinderP pass]
alt_bndrs = []
, alt_rhs :: forall (pass :: StgPass). GenStgAlt pass -> GenStgExpr pass
alt_rhs = GenStgExpr 'Vanilla
rhs}]
| Id -> Bool
isUnboxedSumBndr Id
bndr
= do (rho_sum_bndrs, sum_bndrs) <- UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseConArgBinder UnariseEnv
rho Id
bndr
rhs' <- unariseExpr rho_sum_bndrs rhs
return [GenStgAlt (DataAlt (tupleDataCon Unboxed (length sum_bndrs))) sum_bndrs rhs']
unariseAlts UnariseEnv
rho (MultiValAlt Int
_) Id
bndr [GenStgAlt 'Vanilla]
alts
| Id -> Bool
isUnboxedSumBndr Id
bndr
= do (rho_sum_bndrs, scrt_bndrs@(tag_bndr : real_bndrs)) <- UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseConArgBinder UnariseEnv
rho Id
bndr
alts' <- unariseSumAlts rho_sum_bndrs (map StgVarArg real_bndrs) alts
let inner_case = GenStgExpr 'Vanilla
-> BinderP 'Vanilla
-> AltType
-> [GenStgAlt 'Vanilla]
-> GenStgExpr 'Vanilla
forall (pass :: StgPass).
GenStgExpr pass
-> BinderP pass -> AltType -> [GenStgAlt pass] -> GenStgExpr pass
StgCase (Id -> [StgArg] -> GenStgExpr 'Vanilla
forall (pass :: StgPass). Id -> [StgArg] -> GenStgExpr pass
StgApp Id
tag_bndr []) Id
BinderP 'Vanilla
tag_bndr AltType
tagAltTy [GenStgAlt 'Vanilla]
alts'
return [GenStgAlt{ alt_con = DataAlt (tupleDataCon Unboxed (length scrt_bndrs))
, alt_bndrs = scrt_bndrs
, alt_rhs = inner_case
}]
unariseAlts UnariseEnv
rho AltType
_ Id
_ [GenStgAlt 'Vanilla]
alts
= (GenStgAlt 'Vanilla -> UniqSM (GenStgAlt 'Vanilla))
-> [GenStgAlt 'Vanilla] -> UniqSM [GenStgAlt 'Vanilla]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (\GenStgAlt 'Vanilla
alt -> UnariseEnv -> GenStgAlt 'Vanilla -> UniqSM (GenStgAlt 'Vanilla)
unariseAlt UnariseEnv
rho GenStgAlt 'Vanilla
alt) [GenStgAlt 'Vanilla]
alts
unariseAlt :: UnariseEnv -> StgAlt -> UniqSM StgAlt
unariseAlt :: UnariseEnv -> GenStgAlt 'Vanilla -> UniqSM (GenStgAlt 'Vanilla)
unariseAlt UnariseEnv
rho alt :: GenStgAlt 'Vanilla
alt@GenStgAlt{alt_con :: forall (pass :: StgPass). GenStgAlt pass -> AltCon
alt_con=AltCon
_,alt_bndrs :: forall (pass :: StgPass). GenStgAlt pass -> [BinderP pass]
alt_bndrs=[BinderP 'Vanilla]
xs,alt_rhs :: forall (pass :: StgPass). GenStgAlt pass -> GenStgExpr pass
alt_rhs=GenStgExpr 'Vanilla
e}
= do (rho', xs') <- UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [Id])
unariseConArgBinders UnariseEnv
rho [Id]
[BinderP 'Vanilla]
xs
!e' <- unariseExpr rho' e
return $! alt {alt_bndrs = xs', alt_rhs = e'}
unariseSumAlts :: UnariseEnv
-> [StgArg]
-> [StgAlt]
-> UniqSM [StgAlt]
unariseSumAlts :: UnariseEnv
-> [StgArg] -> [GenStgAlt 'Vanilla] -> UniqSM [GenStgAlt 'Vanilla]
unariseSumAlts UnariseEnv
env [StgArg]
args [GenStgAlt 'Vanilla]
alts
= do alts' <- (GenStgAlt 'Vanilla -> UniqSM (GenStgAlt 'Vanilla))
-> [GenStgAlt 'Vanilla] -> UniqSM [GenStgAlt 'Vanilla]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (UnariseEnv
-> [StgArg] -> GenStgAlt 'Vanilla -> UniqSM (GenStgAlt 'Vanilla)
unariseSumAlt UnariseEnv
env [StgArg]
args) [GenStgAlt 'Vanilla]
alts
return (mkDefaultLitAlt alts')
unariseSumAlt :: UnariseEnv
-> [StgArg]
-> StgAlt
-> UniqSM StgAlt
unariseSumAlt :: UnariseEnv
-> [StgArg] -> GenStgAlt 'Vanilla -> UniqSM (GenStgAlt 'Vanilla)
unariseSumAlt UnariseEnv
rho [StgArg]
_ GenStgAlt{alt_con :: forall (pass :: StgPass). GenStgAlt pass -> AltCon
alt_con=AltCon
DEFAULT,alt_bndrs :: forall (pass :: StgPass). GenStgAlt pass -> [BinderP pass]
alt_bndrs=[BinderP 'Vanilla]
_,alt_rhs :: forall (pass :: StgPass). GenStgAlt pass -> GenStgExpr pass
alt_rhs=GenStgExpr 'Vanilla
e}
= AltCon
-> [BinderP 'Vanilla] -> GenStgExpr 'Vanilla -> GenStgAlt 'Vanilla
forall (pass :: StgPass).
AltCon -> [BinderP pass] -> GenStgExpr pass -> GenStgAlt pass
GenStgAlt AltCon
DEFAULT [Id]
[BinderP 'Vanilla]
forall a. Monoid a => a
mempty (GenStgExpr 'Vanilla -> GenStgAlt 'Vanilla)
-> UniqSM (GenStgExpr 'Vanilla) -> UniqSM (GenStgAlt 'Vanilla)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UnariseEnv -> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
unariseExpr UnariseEnv
rho GenStgExpr 'Vanilla
e
unariseSumAlt UnariseEnv
rho [StgArg]
args alt :: GenStgAlt 'Vanilla
alt@GenStgAlt{ alt_con :: forall (pass :: StgPass). GenStgAlt pass -> AltCon
alt_con = DataAlt DataCon
sumCon
, alt_bndrs :: forall (pass :: StgPass). GenStgAlt pass -> [BinderP pass]
alt_bndrs = [BinderP 'Vanilla]
bs
, alt_rhs :: forall (pass :: StgPass). GenStgAlt pass -> GenStgExpr pass
alt_rhs = GenStgExpr 'Vanilla
e
}
= do (rho',e') <- case [BinderP 'Vanilla]
bs of
[BinderP 'Vanilla
b] -> Id
-> [StgArg]
-> GenStgExpr 'Vanilla
-> UnariseEnv
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
mapSumIdBinders Id
BinderP 'Vanilla
b [StgArg]
args GenStgExpr 'Vanilla
e UnariseEnv
rho
[BinderP 'Vanilla]
_ -> String -> SDoc -> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"unariseSumAlt2" ([StgArg] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [StgArg]
args SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ GenStgAlt 'Vanilla -> SDoc
forall (pass :: StgPass).
OutputablePass pass =>
GenStgAlt pass -> SDoc
pprPanicAlt GenStgAlt 'Vanilla
alt)
let lit_case = Literal -> AltCon
LitAlt (LitNumType -> Integer -> Literal
LitNumber LitNumType
LitNumInt (Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (DataCon -> Int
dataConTag DataCon
sumCon)))
GenStgAlt lit_case mempty <$> unariseExpr rho' e'
unariseSumAlt UnariseEnv
_ [StgArg]
scrt GenStgAlt 'Vanilla
alt
= String -> SDoc -> UniqSM (GenStgAlt 'Vanilla)
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"unariseSumAlt3" ([StgArg] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [StgArg]
scrt SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ GenStgAlt 'Vanilla -> SDoc
forall (pass :: StgPass).
OutputablePass pass =>
GenStgAlt pass -> SDoc
pprPanicAlt GenStgAlt 'Vanilla
alt)
mapTupleIdBinders
:: [InId]
-> [OutStgArg]
-> UnariseEnv
-> UnariseEnv
mapTupleIdBinders :: [Id] -> [StgArg] -> UnariseEnv -> UnariseEnv
mapTupleIdBinders [Id]
ids [StgArg]
args0 UnariseEnv
rho0
= Bool -> UnariseEnv -> UnariseEnv
forall a. HasCallStack => Bool -> a -> a
assert (Bool -> Bool
not ((StgArg -> Bool) -> [StgArg] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ([PrimRep] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([PrimRep] -> Bool) -> (StgArg -> [PrimRep]) -> StgArg -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StgArg -> [PrimRep]
stgArgRep) [StgArg]
args0)) (UnariseEnv -> UnariseEnv) -> UnariseEnv -> UnariseEnv
forall a b. (a -> b) -> a -> b
$
let
map_ids :: UnariseEnv -> [Id] -> [StgArg] -> UnariseEnv
map_ids :: UnariseEnv -> [Id] -> [StgArg] -> UnariseEnv
map_ids UnariseEnv
rho [] [StgArg]
_ = UnariseEnv
rho
map_ids UnariseEnv
rho (Id
x : [Id]
xs) [StgArg]
args =
let
x_reps :: [PrimRep]
x_reps = HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
typePrimRep (Id -> Type
idType Id
x)
x_arity :: Int
x_arity = [PrimRep] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [PrimRep]
x_reps
([StgArg]
x_args, [StgArg]
args') =
Bool
-> (Int -> [StgArg] -> ([StgArg], [StgArg]))
-> Int
-> [StgArg]
-> ([StgArg], [StgArg])
forall a. HasCallStack => Bool -> a -> a
assert ([StgArg]
args [StgArg] -> Int -> Bool
forall a. [a] -> Int -> Bool
`lengthAtLeast` Int
x_arity)
Int -> [StgArg] -> ([StgArg], [StgArg])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
x_arity [StgArg]
args
rho' :: UnariseEnv
rho'
| Int
x_arity Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
= Bool
-> (UnariseEnv -> Id -> UnariseVal -> UnariseEnv)
-> UnariseEnv
-> Id
-> UnariseVal
-> UnariseEnv
forall a. HasCallStack => Bool -> a -> a
assert ([StgArg]
x_args [StgArg] -> Int -> Bool
forall a. [a] -> Int -> Bool
`lengthIs` Int
1)
UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho Id
x (StgArg -> UnariseVal
UnaryVal ([StgArg] -> StgArg
forall a. HasCallStack => [a] -> a
head [StgArg]
x_args))
| Bool
otherwise
= UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho Id
x ([StgArg] -> UnariseVal
MultiVal [StgArg]
x_args)
in
UnariseEnv -> [Id] -> [StgArg] -> UnariseEnv
map_ids UnariseEnv
rho' [Id]
xs [StgArg]
args'
in
UnariseEnv -> [Id] -> [StgArg] -> UnariseEnv
map_ids UnariseEnv
rho0 [Id]
ids [StgArg]
args0
mapSumIdBinders
:: InId
-> [OutStgArg]
-> InStgExpr
-> UnariseEnv
-> UniqSM (UnariseEnv, OutStgExpr)
mapSumIdBinders :: Id
-> [StgArg]
-> GenStgExpr 'Vanilla
-> UnariseEnv
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
mapSumIdBinders Id
alt_bndr [StgArg]
args GenStgExpr 'Vanilla
rhs UnariseEnv
rho0
= Bool
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
forall a. HasCallStack => Bool -> a -> a
assert (Bool -> Bool
not ((StgArg -> Bool) -> [StgArg] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ([PrimRep] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([PrimRep] -> Bool) -> (StgArg -> [PrimRep]) -> StgArg -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StgArg -> [PrimRep]
stgArgRep) [StgArg]
args)) (UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla))
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
-> UniqSM (UnariseEnv, GenStgExpr 'Vanilla)
forall a b. (a -> b) -> a -> b
$ do
uss <- UniqSupply -> [UniqSupply]
listSplitUniqSupply (UniqSupply -> [UniqSupply])
-> UniqSM UniqSupply -> UniqSM [UniqSupply]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UniqSM UniqSupply
forall (m :: * -> *). MonadUnique m => m UniqSupply
getUniqueSupplyM
let
fld_reps = HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
typePrimRep (Id -> Type
idType Id
alt_bndr)
arg_slots = (PrimRep -> SlotTy) -> [PrimRep] -> [SlotTy]
forall a b. (a -> b) -> [a] -> [b]
map PrimRep -> SlotTy
primRepSlot ([PrimRep] -> [SlotTy]) -> [PrimRep] -> [SlotTy]
forall a b. (a -> b) -> a -> b
$ (StgArg -> [PrimRep]) -> [StgArg] -> [PrimRep]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap StgArg -> [PrimRep]
stgArgRep [StgArg]
args
id_slots = (PrimRep -> SlotTy) -> [PrimRep] -> [SlotTy]
forall a b. (a -> b) -> [a] -> [b]
map PrimRep -> SlotTy
primRepSlot ([PrimRep] -> [SlotTy]) -> [PrimRep] -> [SlotTy]
forall a b. (a -> b) -> a -> b
$ [PrimRep]
fld_reps
layout1 = [SlotTy] -> [SlotTy] -> [Int]
HasDebugCallStack => [SlotTy] -> [SlotTy] -> [Int]
layoutUbxSum [SlotTy]
arg_slots [SlotTy]
id_slots
id_arg_exprs = [ [StgArg]
args [StgArg] -> Int -> StgArg
forall a. HasCallStack => [a] -> Int -> a
!! Int
i | Int
i <- [Int]
layout1 ]
id_vars = [Id
v | StgVarArg Id
v <- [StgArg]
id_arg_exprs]
typed_id_arg_input = Bool -> [(Id, PrimRep, UniqSupply)] -> [(Id, PrimRep, UniqSupply)]
forall a. HasCallStack => Bool -> a -> a
assert ([Id] -> [PrimRep] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [Id]
id_vars [PrimRep]
fld_reps) ([(Id, PrimRep, UniqSupply)] -> [(Id, PrimRep, UniqSupply)])
-> [(Id, PrimRep, UniqSupply)] -> [(Id, PrimRep, UniqSupply)]
forall a b. (a -> b) -> a -> b
$
[Id] -> [PrimRep] -> [UniqSupply] -> [(Id, PrimRep, UniqSupply)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [Id]
id_vars [PrimRep]
fld_reps [UniqSupply]
uss
mkCastInput :: (Id,PrimRep,UniqSupply) -> ([(PrimOp,Type,Unique)],Id,Id)
mkCastInput (Id
id,PrimRep
rep,UniqSupply
bndr_us) =
let ([PrimOp]
ops,[Type]
types) = [(PrimOp, Type)] -> ([PrimOp], [Type])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(PrimOp, Type)] -> ([PrimOp], [Type]))
-> [(PrimOp, Type)] -> ([PrimOp], [Type])
forall a b. (a -> b) -> a -> b
$ PrimRep -> PrimRep -> [(PrimOp, Type)]
getCasts (HasDebugCallStack => Type -> PrimRep
Type -> PrimRep
typePrimRepU (Type -> PrimRep) -> Type -> PrimRep
forall a b. (a -> b) -> a -> b
$ Id -> Type
idType Id
id) PrimRep
rep
cst_opts :: [(PrimOp, Type, Unique)]
cst_opts = [PrimOp] -> [Type] -> [Unique] -> [(PrimOp, Type, Unique)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [PrimOp]
ops [Type]
types ([Unique] -> [(PrimOp, Type, Unique)])
-> [Unique] -> [(PrimOp, Type, Unique)]
forall a b. (a -> b) -> a -> b
$ UniqSupply -> [Unique]
uniqsFromSupply UniqSupply
bndr_us
out_id :: Id
out_id = case [(PrimOp, Type, Unique)]
cst_opts of
[] -> Id
id
[(PrimOp, Type, Unique)]
_ -> let (PrimOp
_,Type
ty,Unique
uq) = [(PrimOp, Type, Unique)] -> (PrimOp, Type, Unique)
forall a. HasCallStack => [a] -> a
last [(PrimOp, Type, Unique)]
cst_opts
in Unique -> Type -> Id
mkCastVar Unique
uq Type
ty
in ([(PrimOp, Type, Unique)]
cst_opts,Id
id,Id
out_id)
cast_inputs = ((Id, PrimRep, UniqSupply) -> ([(PrimOp, Type, Unique)], Id, Id))
-> [(Id, PrimRep, UniqSupply)]
-> [([(PrimOp, Type, Unique)], Id, Id)]
forall a b. (a -> b) -> [a] -> [b]
map (Id, PrimRep, UniqSupply) -> ([(PrimOp, Type, Unique)], Id, Id)
mkCastInput [(Id, PrimRep, UniqSupply)]
typed_id_arg_input
(rhs_with_casts,typed_ids) = mapAccumL cast_arg (\GenStgExpr 'Vanilla
x->GenStgExpr 'Vanilla
x) cast_inputs
where
cast_arg GenStgExpr 'Vanilla -> c
rhs_in ([(PrimOp, Type, Unique)]
cast_ops,Id
in_id,b
out_id) =
let rhs_out :: GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
rhs_out = [(PrimOp, Type, Unique)]
-> StgArg -> GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
castArgRename [(PrimOp, Type, Unique)]
cast_ops (Id -> StgArg
StgVarArg Id
in_id)
in (GenStgExpr 'Vanilla -> c
rhs_in (GenStgExpr 'Vanilla -> c)
-> (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> GenStgExpr 'Vanilla
-> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
rhs_out, b
out_id)
typed_id_args = (Id -> StgArg) -> [Id] -> [StgArg]
forall a b. (a -> b) -> [a] -> [b]
map Id -> StgArg
StgVarArg [Id]
typed_ids
if isMultiValBndr alt_bndr
then return (extendRho rho0 alt_bndr (MultiVal typed_id_args), rhs_with_casts rhs)
else assert (typed_id_args `lengthIs` 1) $
return (extendRho rho0 alt_bndr (UnaryVal (head typed_id_args)), rhs_with_casts rhs)
castArgRename :: [(PrimOp,Type,Unique)] -> StgArg -> StgExpr -> StgExpr
castArgRename :: [(PrimOp, Type, Unique)]
-> StgArg -> GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
castArgRename [(PrimOp, Type, Unique)]
ops StgArg
in_arg GenStgExpr 'Vanilla
rhs =
case [(PrimOp, Type, Unique)]
ops of
[] -> GenStgExpr 'Vanilla
rhs
((PrimOp
op,Type
ty,Unique
uq):[(PrimOp, Type, Unique)]
rest_ops) ->
let out_id' :: Id
out_id' = Unique -> Type -> Id
mkCastVar Unique
uq Type
ty
sub_cast :: GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
sub_cast = [(PrimOp, Type, Unique)]
-> StgArg -> GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
castArgRename [(PrimOp, Type, Unique)]
rest_ops (Id -> StgArg
StgVarArg Id
out_id')
in StgArg
-> PrimOp
-> Id
-> Type
-> GenStgExpr 'Vanilla
-> GenStgExpr 'Vanilla
mkCast StgArg
in_arg PrimOp
op Id
out_id' Type
ty (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
forall a b. (a -> b) -> a -> b
$ GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
sub_cast GenStgExpr 'Vanilla
rhs
mkCastVar :: Unique -> Type -> Id
mkCastVar :: Unique -> Type -> Id
mkCastVar Unique
uq Type
ty = FastString -> Unique -> Type -> Type -> Id
mkSysLocal (String -> FastString
fsLit String
"cst_sum") Unique
uq Type
ManyTy Type
ty
mkCast :: StgArg -> PrimOp -> OutId -> Type -> StgExpr -> StgExpr
mkCast :: StgArg
-> PrimOp
-> Id
-> Type
-> GenStgExpr 'Vanilla
-> GenStgExpr 'Vanilla
mkCast StgArg
arg_in PrimOp
cast_op Id
out_id Type
out_ty GenStgExpr 'Vanilla
in_rhs =
let r2 :: PrimRep
r2 = HasDebugCallStack => Type -> PrimRep
Type -> PrimRep
typePrimRepU Type
out_ty
scrut :: GenStgExpr 'Vanilla
scrut = StgOp -> [StgArg] -> Type -> GenStgExpr 'Vanilla
forall (pass :: StgPass).
StgOp -> [StgArg] -> Type -> GenStgExpr pass
StgOpApp (PrimOp -> StgOp
StgPrimOp PrimOp
cast_op) [StgArg
arg_in] Type
out_ty
alt :: GenStgAlt 'Vanilla
alt = GenStgAlt { alt_con :: AltCon
alt_con = AltCon
DEFAULT, alt_bndrs :: [BinderP 'Vanilla]
alt_bndrs = [], alt_rhs :: GenStgExpr 'Vanilla
alt_rhs = GenStgExpr 'Vanilla
in_rhs}
alt_ty :: AltType
alt_ty = PrimRep -> AltType
PrimAlt PrimRep
r2
in (GenStgExpr 'Vanilla
-> BinderP 'Vanilla
-> AltType
-> [GenStgAlt 'Vanilla]
-> GenStgExpr 'Vanilla
forall (pass :: StgPass).
GenStgExpr pass
-> BinderP pass -> AltType -> [GenStgAlt pass] -> GenStgExpr pass
StgCase GenStgExpr 'Vanilla
scrut Id
BinderP 'Vanilla
out_id AltType
alt_ty [GenStgAlt 'Vanilla
alt])
mkUbxSum
:: HasDebugCallStack
=> DataCon
-> [[PrimRep]]
-> [OutStgArg]
-> UniqSupply
-> ([OutStgArg]
,(StgExpr->StgExpr)
)
mkUbxSum :: HasDebugCallStack =>
DataCon
-> [[PrimRep]]
-> [StgArg]
-> UniqSupply
-> ([StgArg], GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
mkUbxSum DataCon
dc [[PrimRep]]
ty_args [StgArg]
args0 UniqSupply
us
= let
SlotTy
_ :| [SlotTy]
sum_slots = [[PrimRep]] -> NonEmpty SlotTy
ubxSumRepType [[PrimRep]]
ty_args
field_slots :: [SlotTy]
field_slots = ((StgArg -> Maybe SlotTy) -> [StgArg] -> [SlotTy]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ([PrimRep] -> Maybe SlotTy
repSlotTy ([PrimRep] -> Maybe SlotTy)
-> (StgArg -> [PrimRep]) -> StgArg -> Maybe SlotTy
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StgArg -> [PrimRep]
stgArgRep) [StgArg]
args0)
tag :: Int
tag = DataCon -> Int
dataConTag DataCon
dc
layout' :: [Int]
layout' = [SlotTy] -> [SlotTy] -> [Int]
HasDebugCallStack => [SlotTy] -> [SlotTy] -> [Int]
layoutUbxSum [SlotTy]
sum_slots [SlotTy]
field_slots
tag_arg :: StgArg
tag_arg = Literal -> StgArg
StgLitArg (LitNumType -> Integer -> Literal
LitNumber LitNumType
LitNumInt (Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
tag))
arg_idxs :: IntMap StgArg
arg_idxs = [(Int, StgArg)] -> IntMap StgArg
forall a. [(Int, a)] -> IntMap a
IM.fromList (String -> [Int] -> [StgArg] -> [(Int, StgArg)]
forall a b. HasDebugCallStack => String -> [a] -> [b] -> [(a, b)]
zipEqual String
"mkUbxSum" [Int]
layout' [StgArg]
args0)
((Int
_idx,IntMap StgArg
_idx_map,UniqSupply
_us,GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
wrapper),[StgArg]
slot_args)
= Bool
-> ((Int, IntMap StgArg, UniqSupply,
GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla),
[StgArg])
-> ((Int, IntMap StgArg, UniqSupply,
GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla),
[StgArg])
forall a. HasCallStack => Bool -> a -> a
assert (IntMap StgArg -> Int
forall a. IntMap a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length IntMap StgArg
arg_idxs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= [SlotTy] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [SlotTy]
sum_slots ) (((Int, IntMap StgArg, UniqSupply,
GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla),
[StgArg])
-> ((Int, IntMap StgArg, UniqSupply,
GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla),
[StgArg]))
-> ((Int, IntMap StgArg, UniqSupply,
GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla),
[StgArg])
-> ((Int, IntMap StgArg, UniqSupply,
GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla),
[StgArg])
forall a b. (a -> b) -> a -> b
$
((Int, IntMap StgArg, UniqSupply,
GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> SlotTy
-> ((Int, IntMap StgArg, UniqSupply,
GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla),
StgArg))
-> (Int, IntMap StgArg, UniqSupply,
GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> [SlotTy]
-> ((Int, IntMap StgArg, UniqSupply,
GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla),
[StgArg])
forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
mapAccumL (Int, IntMap StgArg, UniqSupply,
GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> SlotTy
-> ((Int, IntMap StgArg, UniqSupply,
GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla),
StgArg)
mkTupArg (Int
0,IntMap StgArg
arg_idxs,UniqSupply
us,GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
forall a. a -> a
id) [SlotTy]
sum_slots
mkTupArg :: (Int, IM.IntMap StgArg,UniqSupply,StgExpr->StgExpr)
-> SlotTy
-> ((Int,IM.IntMap StgArg,UniqSupply,StgExpr->StgExpr), StgArg)
mkTupArg :: (Int, IntMap StgArg, UniqSupply,
GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> SlotTy
-> ((Int, IntMap StgArg, UniqSupply,
GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla),
StgArg)
mkTupArg (Int
arg_idx, IntMap StgArg
arg_map, UniqSupply
us, GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
wrapper) SlotTy
slot
| Just StgArg
stg_arg <- Int -> IntMap StgArg -> Maybe StgArg
forall a. Int -> IntMap a -> Maybe a
IM.lookup Int
arg_idx IntMap StgArg
arg_map
= case UniqSupply
-> SlotTy
-> StgArg
-> Maybe
(StgArg, UniqSupply, GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
castArg UniqSupply
us SlotTy
slot StgArg
stg_arg of
Just (StgArg
casted_arg,UniqSupply
us',GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
wrapper') ->
( (Int
arg_idxInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1, IntMap StgArg
arg_map, UniqSupply
us', GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
wrapper (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> GenStgExpr 'Vanilla
-> GenStgExpr 'Vanilla
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
wrapper')
, StgArg
casted_arg)
Maybe
(StgArg, UniqSupply, GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
Nothing ->
( (Int
arg_idxInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1, IntMap StgArg
arg_map, UniqSupply
us, GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
wrapper)
, StgArg
stg_arg)
| Bool
otherwise
= ( (Int
arg_idxInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1, IntMap StgArg
arg_map, UniqSupply
us, GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
wrapper)
, SlotTy -> StgArg
ubxSumRubbishArg SlotTy
slot)
castArg :: UniqSupply -> SlotTy -> StgArg -> Maybe (StgArg,UniqSupply,StgExpr -> StgExpr)
castArg :: UniqSupply
-> SlotTy
-> StgArg
-> Maybe
(StgArg, UniqSupply, GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
castArg UniqSupply
us SlotTy
slot_ty StgArg
arg
| SlotTy -> PrimRep
slotPrimRep SlotTy
slot_ty PrimRep -> PrimRep -> Bool
forall a. Eq a => a -> a -> Bool
/= StgArg -> PrimRep
stgArgRepU StgArg
arg
, ([PrimOp]
ops,[Type]
types) <- [(PrimOp, Type)] -> ([PrimOp], [Type])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(PrimOp, Type)] -> ([PrimOp], [Type]))
-> [(PrimOp, Type)] -> ([PrimOp], [Type])
forall a b. (a -> b) -> a -> b
$ PrimRep -> PrimRep -> [(PrimOp, Type)]
getCasts (StgArg -> PrimRep
stgArgRepU StgArg
arg) (PrimRep -> [(PrimOp, Type)]) -> PrimRep -> [(PrimOp, Type)]
forall a b. (a -> b) -> a -> b
$ SlotTy -> PrimRep
slotPrimRep SlotTy
slot_ty
, Bool -> Bool
not (Bool -> Bool) -> ([PrimOp] -> Bool) -> [PrimOp] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [PrimOp] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([PrimOp] -> Bool) -> [PrimOp] -> Bool
forall a b. (a -> b) -> a -> b
$ [PrimOp]
ops
= let (UniqSupply
us1,UniqSupply
us2) = UniqSupply -> (UniqSupply, UniqSupply)
splitUniqSupply UniqSupply
us
cast_uqs :: [Unique]
cast_uqs = UniqSupply -> [Unique]
uniqsFromSupply UniqSupply
us1
cast_opts :: [(PrimOp, Type, Unique)]
cast_opts = [PrimOp] -> [Type] -> [Unique] -> [(PrimOp, Type, Unique)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [PrimOp]
ops [Type]
types [Unique]
cast_uqs
(PrimOp
_op,Type
out_ty,Unique
out_uq) = [(PrimOp, Type, Unique)] -> (PrimOp, Type, Unique)
forall a. HasCallStack => [a] -> a
last [(PrimOp, Type, Unique)]
cast_opts
casts :: GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
casts = [(PrimOp, Type, Unique)]
-> StgArg -> GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
castArgRename [(PrimOp, Type, Unique)]
cast_opts StgArg
arg :: StgExpr -> StgExpr
in (StgArg, UniqSupply, GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> Maybe
(StgArg, UniqSupply, GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
forall a. a -> Maybe a
Just (Id -> StgArg
StgVarArg (Unique -> Type -> Id
mkCastVar Unique
out_uq Type
out_ty),UniqSupply
us2,GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
casts)
| Bool
otherwise = Maybe
(StgArg, UniqSupply, GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
forall a. Maybe a
Nothing
tup_args :: [StgArg]
tup_args = StgArg
tag_arg StgArg -> [StgArg] -> [StgArg]
forall a. a -> [a] -> [a]
: [StgArg]
slot_args
in
([StgArg]
tup_args, GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
wrapper)
ubxSumRubbishArg :: SlotTy -> StgArg
ubxSumRubbishArg :: SlotTy -> StgArg
ubxSumRubbishArg SlotTy
PtrLiftedSlot = Id -> StgArg
StgVarArg Id
aBSENT_SUM_FIELD_ERROR_ID
ubxSumRubbishArg SlotTy
PtrUnliftedSlot = Id -> StgArg
StgVarArg Id
aBSENT_SUM_FIELD_ERROR_ID
ubxSumRubbishArg SlotTy
WordSlot = Literal -> StgArg
StgLitArg (LitNumType -> Integer -> Literal
LitNumber LitNumType
LitNumWord Integer
0)
ubxSumRubbishArg SlotTy
Word64Slot = Literal -> StgArg
StgLitArg (LitNumType -> Integer -> Literal
LitNumber LitNumType
LitNumWord64 Integer
0)
ubxSumRubbishArg SlotTy
FloatSlot = Literal -> StgArg
StgLitArg (Rational -> Literal
LitFloat Rational
0)
ubxSumRubbishArg SlotTy
DoubleSlot = Literal -> StgArg
StgLitArg (Rational -> Literal
LitDouble Rational
0)
ubxSumRubbishArg (VecSlot Int
n PrimElemRep
e) = Literal -> StgArg
StgLitArg (TypeOrConstraint -> Type -> Literal
LitRubbish TypeOrConstraint
TypeLike Type
vec_rep)
where vec_rep :: Type
vec_rep = PrimRep -> Type
primRepToRuntimeRep (Int -> PrimElemRep -> PrimRep
VecRep Int
n PrimElemRep
e)
unariseArgBinder
:: Bool
-> UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseArgBinder :: Bool -> UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseArgBinder Bool
is_con_arg UnariseEnv
rho Id
x =
case HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
typePrimRep (Id -> Type
idType Id
x) of
[]
| Bool
is_con_arg
-> (UnariseEnv, [Id]) -> UniqSM (UnariseEnv, [Id])
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho Id
x ([StgArg] -> UnariseVal
MultiVal []), [])
| Bool
otherwise
-> (UnariseEnv, [Id]) -> UniqSM (UnariseEnv, [Id])
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho Id
x ([StgArg] -> UnariseVal
MultiVal []), [Id
voidArgId])
[PrimRep
rep]
| Type -> Bool
isUnboxedSumType (Id -> Type
idType Id
x) Bool -> Bool -> Bool
|| Type -> Bool
isUnboxedTupleType (Id -> Type
idType Id
x)
-> do x' <- FastString -> Type -> UniqSM Id
mkId (String -> FastString
mkFastString String
"us") (PrimRep -> Type
primRepToType PrimRep
rep)
return (extendRho rho x (MultiVal [StgVarArg x']), [x'])
| Bool
otherwise
-> (UnariseEnv, [Id]) -> UniqSM (UnariseEnv, [Id])
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (UnariseEnv -> Id -> UnariseEnv
extendRhoWithoutValue UnariseEnv
rho Id
x, [Id
x])
[PrimRep]
reps -> do
xs <- FastString -> [Type] -> UniqSM [Id]
mkIds (String -> FastString
mkFastString String
"us") ((PrimRep -> Type) -> [PrimRep] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map PrimRep -> Type
primRepToType [PrimRep]
reps)
return (extendRho rho x (MultiVal (map StgVarArg xs)), xs)
unariseFunArg :: UnariseEnv -> StgArg -> [StgArg]
unariseFunArg :: UnariseEnv -> StgArg -> [StgArg]
unariseFunArg UnariseEnv
rho (StgVarArg Id
x) =
case UnariseEnv -> Id -> Maybe UnariseVal
lookupRho UnariseEnv
rho Id
x of
Just (MultiVal []) -> [StgArg
voidArg]
Just (MultiVal [StgArg]
as) -> [StgArg]
as
Just (UnaryVal StgArg
arg) -> [StgArg
arg]
Maybe UnariseVal
Nothing -> [Id -> StgArg
StgVarArg Id
x]
unariseFunArg UnariseEnv
_ arg :: StgArg
arg@(StgLitArg Literal
lit) = case Literal -> Maybe [StgArg]
unariseLiteral_maybe Literal
lit of
Just [] -> [StgArg
voidArg]
Just [StgArg]
as -> [StgArg]
as
Maybe [StgArg]
Nothing -> [StgArg
arg]
unariseFunArgs :: UnariseEnv -> [StgArg] -> [StgArg]
unariseFunArgs :: UnariseEnv -> [StgArg] -> [StgArg]
unariseFunArgs = (StgArg -> [StgArg]) -> [StgArg] -> [StgArg]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((StgArg -> [StgArg]) -> [StgArg] -> [StgArg])
-> (UnariseEnv -> StgArg -> [StgArg])
-> UnariseEnv
-> [StgArg]
-> [StgArg]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnariseEnv -> StgArg -> [StgArg]
unariseFunArg
unariseFunArgBinders :: UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [Id])
unariseFunArgBinders :: UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [Id])
unariseFunArgBinders UnariseEnv
rho [Id]
xs = ([[Id]] -> [Id]) -> (UnariseEnv, [[Id]]) -> (UnariseEnv, [Id])
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second [[Id]] -> [Id]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ((UnariseEnv, [[Id]]) -> (UnariseEnv, [Id]))
-> UniqSM (UnariseEnv, [[Id]]) -> UniqSM (UnariseEnv, [Id])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id]))
-> UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [[Id]])
forall (m :: * -> *) (t :: * -> *) acc x y.
(Monad m, Traversable t) =>
(acc -> x -> m (acc, y)) -> acc -> t x -> m (acc, t y)
mapAccumLM UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseFunArgBinder UnariseEnv
rho [Id]
xs
unariseFunArgBinder :: UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseFunArgBinder :: UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseFunArgBinder = Bool -> UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseArgBinder Bool
False
unariseConArg :: UnariseEnv -> InStgArg -> [OutStgArg]
unariseConArg :: UnariseEnv -> StgArg -> [StgArg]
unariseConArg UnariseEnv
rho (StgVarArg Id
x) =
case UnariseEnv -> Id -> Maybe UnariseVal
lookupRho UnariseEnv
rho Id
x of
Just (UnaryVal StgArg
arg) -> [StgArg
arg]
Just (MultiVal [StgArg]
as) -> [StgArg]
as
Maybe UnariseVal
Nothing
| HasDebugCallStack => Type -> Bool
Type -> Bool
isZeroBitTy (Id -> Type
idType Id
x) -> []
| Bool
otherwise -> [Id -> StgArg
StgVarArg Id
x]
unariseConArg UnariseEnv
_ arg :: StgArg
arg@(StgLitArg Literal
lit)
| Just [StgArg]
as <- Literal -> Maybe [StgArg]
unariseLiteral_maybe Literal
lit
= [StgArg]
as
| Bool
otherwise
= Bool -> [StgArg] -> [StgArg]
forall a. HasCallStack => Bool -> a -> a
assert ([PrimRep] -> Bool
isNvUnaryRep (HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
typePrimRep (Literal -> Type
literalType Literal
lit)))
[StgArg
arg]
unariseConArgs :: UnariseEnv -> [InStgArg] -> [OutStgArg]
unariseConArgs :: UnariseEnv -> [StgArg] -> [StgArg]
unariseConArgs = (StgArg -> [StgArg]) -> [StgArg] -> [StgArg]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((StgArg -> [StgArg]) -> [StgArg] -> [StgArg])
-> (UnariseEnv -> StgArg -> [StgArg])
-> UnariseEnv
-> [StgArg]
-> [StgArg]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnariseEnv -> StgArg -> [StgArg]
unariseConArg
unariseConArgBinders :: UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [Id])
unariseConArgBinders :: UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [Id])
unariseConArgBinders UnariseEnv
rho [Id]
xs = ([[Id]] -> [Id]) -> (UnariseEnv, [[Id]]) -> (UnariseEnv, [Id])
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second [[Id]] -> [Id]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ((UnariseEnv, [[Id]]) -> (UnariseEnv, [Id]))
-> UniqSM (UnariseEnv, [[Id]]) -> UniqSM (UnariseEnv, [Id])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id]))
-> UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [[Id]])
forall (m :: * -> *) (t :: * -> *) acc x y.
(Monad m, Traversable t) =>
(acc -> x -> m (acc, y)) -> acc -> t x -> m (acc, t y)
mapAccumLM UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseConArgBinder UnariseEnv
rho [Id]
xs
unariseConArgBinder :: UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseConArgBinder :: UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseConArgBinder = Bool -> UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseArgBinder Bool
True
mkIds :: FastString -> [NvUnaryType] -> UniqSM [Id]
mkIds :: FastString -> [Type] -> UniqSM [Id]
mkIds FastString
fs [Type]
tys = FastString -> [Type] -> UniqSM [Id]
forall (m :: * -> *).
MonadUnique m =>
FastString -> [Type] -> m [Id]
mkUnarisedIds FastString
fs [Type]
tys
mkId :: FastString -> NvUnaryType -> UniqSM Id
mkId :: FastString -> Type -> UniqSM Id
mkId FastString
s Type
t = FastString -> Type -> UniqSM Id
forall (m :: * -> *). MonadUnique m => FastString -> Type -> m Id
mkUnarisedId FastString
s Type
t
isMultiValBndr :: Id -> Bool
isMultiValBndr :: Id -> Bool
isMultiValBndr Id
id
| [PrimRep
_] <- HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
typePrimRep (Id -> Type
idType Id
id)
= Bool
False
| Bool
otherwise
= Bool
True
isUnboxedSumBndr :: Id -> Bool
isUnboxedSumBndr :: Id -> Bool
isUnboxedSumBndr = Type -> Bool
isUnboxedSumType (Type -> Bool) -> (Id -> Type) -> Id -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> Type
idType
isUnboxedTupleBndr :: Id -> Bool
isUnboxedTupleBndr :: Id -> Bool
isUnboxedTupleBndr = Type -> Bool
isUnboxedTupleType (Type -> Bool) -> (Id -> Type) -> Id -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> Type
idType
mkTuple :: [StgArg] -> StgExpr
mkTuple :: [StgArg] -> GenStgExpr 'Vanilla
mkTuple [StgArg]
args = DataCon
-> ConstructorNumber
-> [StgArg]
-> [[PrimRep]]
-> GenStgExpr 'Vanilla
forall (pass :: StgPass).
DataCon
-> ConstructorNumber -> [StgArg] -> [[PrimRep]] -> GenStgExpr pass
StgConApp (Boxity -> Int -> DataCon
tupleDataCon Boxity
Unboxed ([StgArg] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [StgArg]
args)) ConstructorNumber
NoNumber [StgArg]
args []
tagAltTy :: AltType
tagAltTy :: AltType
tagAltTy = PrimRep -> AltType
PrimAlt PrimRep
IntRep
tagTy :: Type
tagTy :: Type
tagTy = Type
intPrimTy
voidArg :: StgArg
voidArg :: StgArg
voidArg = Id -> StgArg
StgVarArg Id
voidPrimId
mkDefaultLitAlt :: [StgAlt] -> [StgAlt]
mkDefaultLitAlt :: [GenStgAlt 'Vanilla] -> [GenStgAlt 'Vanilla]
mkDefaultLitAlt [] = String -> SDoc -> [GenStgAlt 'Vanilla]
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"elimUbxSumExpr.mkDefaultAlt" (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Empty alts")
mkDefaultLitAlt alts :: [GenStgAlt 'Vanilla]
alts@(GenStgAlt{alt_con :: forall (pass :: StgPass). GenStgAlt pass -> AltCon
alt_con=AltCon
DEFAULT,alt_bndrs :: forall (pass :: StgPass). GenStgAlt pass -> [BinderP pass]
alt_bndrs=[BinderP 'Vanilla]
_,alt_rhs :: forall (pass :: StgPass). GenStgAlt pass -> GenStgExpr pass
alt_rhs=GenStgExpr 'Vanilla
_} : [GenStgAlt 'Vanilla]
_) = [GenStgAlt 'Vanilla]
alts
mkDefaultLitAlt (alt :: GenStgAlt 'Vanilla
alt@GenStgAlt{alt_con :: forall (pass :: StgPass). GenStgAlt pass -> AltCon
alt_con=LitAlt{}, alt_bndrs :: forall (pass :: StgPass). GenStgAlt pass -> [BinderP pass]
alt_bndrs=[]} : [GenStgAlt 'Vanilla]
alts) = GenStgAlt 'Vanilla
alt {alt_con = DEFAULT} GenStgAlt 'Vanilla -> [GenStgAlt 'Vanilla] -> [GenStgAlt 'Vanilla]
forall a. a -> [a] -> [a]
: [GenStgAlt 'Vanilla]
alts
mkDefaultLitAlt [GenStgAlt 'Vanilla]
alts = String -> SDoc -> [GenStgAlt 'Vanilla]
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"mkDefaultLitAlt" (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Not a lit alt:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [GenStgAlt 'Vanilla] -> SDoc
forall (pass :: StgPass).
OutputablePass pass =>
[GenStgAlt pass] -> SDoc
pprPanicAlts [GenStgAlt 'Vanilla]
alts)
pprPanicAlts :: OutputablePass pass => [GenStgAlt pass] -> SDoc
pprPanicAlts :: forall (pass :: StgPass).
OutputablePass pass =>
[GenStgAlt pass] -> SDoc
pprPanicAlts [GenStgAlt pass]
alts = [SDoc] -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((GenStgAlt pass -> SDoc) -> [GenStgAlt pass] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map GenStgAlt pass -> SDoc
forall (pass :: StgPass).
OutputablePass pass =>
GenStgAlt pass -> SDoc
pprPanicAlt [GenStgAlt pass]
alts)
pprPanicAlt :: OutputablePass pass => GenStgAlt pass -> SDoc
pprPanicAlt :: forall (pass :: StgPass).
OutputablePass pass =>
GenStgAlt pass -> SDoc
pprPanicAlt GenStgAlt{alt_con :: forall (pass :: StgPass). GenStgAlt pass -> AltCon
alt_con=AltCon
c,alt_bndrs :: forall (pass :: StgPass). GenStgAlt pass -> [BinderP pass]
alt_bndrs=[BinderP pass]
b,alt_rhs :: forall (pass :: StgPass). GenStgAlt pass -> GenStgExpr pass
alt_rhs=GenStgExpr pass
e} = (AltCon, [BinderP pass], SDoc) -> SDoc
forall a. Outputable a => a -> SDoc
ppr (AltCon
c,[BinderP pass]
b,StgPprOpts -> GenStgExpr pass -> SDoc
forall (pass :: StgPass).
OutputablePass pass =>
StgPprOpts -> GenStgExpr pass -> SDoc
pprStgExpr StgPprOpts
panicStgPprOpts GenStgExpr pass
e)