{-# LANGUAGE CPP, TupleSections #-}
module UnariseStg (unarise) where
#include "HsVersions.h"
import GhcPrelude
import BasicTypes
import CoreSyn
import DataCon
import FastString (FastString, mkFastString)
import Id
import Literal
import MkCore (aBSENT_SUM_FIELD_ERROR_ID)
import MkId (voidPrimId, voidArgId)
import MonadUtils (mapAccumLM)
import Outputable
import RepType
import StgSyn
import Type
import TysPrim (intPrimTy,wordPrimTy,word64PrimTy)
import TysWiredIn
import UniqSupply
import Util
import VarEnv
import Data.Bifunctor (second)
import Data.Maybe (mapMaybe)
import qualified Data.IntMap as IM
type UnariseEnv = VarEnv UnariseVal
data UnariseVal
= MultiVal [OutStgArg]
| UnaryVal OutStgArg
instance Outputable UnariseVal where
ppr :: UnariseVal -> SDoc
ppr (MultiVal args :: [OutStgArg]
args) = String -> SDoc
text "MultiVal" SDoc -> SDoc -> SDoc
<+> [OutStgArg] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [OutStgArg]
args
ppr (UnaryVal arg :: OutStgArg
arg) = String -> SDoc
text "UnaryVal" SDoc -> SDoc -> SDoc
<+> OutStgArg -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutStgArg
arg
extendRho :: UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho :: UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho rho :: UnariseEnv
rho x :: Id
x (MultiVal args :: [OutStgArg]
args)
= ASSERT(all (isNvUnaryType . stgArgType) args)
UnariseEnv -> Id -> UnariseVal -> UnariseEnv
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv UnariseEnv
rho Id
x ([OutStgArg] -> UnariseVal
MultiVal [OutStgArg]
args)
extendRho rho :: UnariseEnv
rho x :: Id
x (UnaryVal val :: OutStgArg
val)
= ASSERT(isNvUnaryType (stgArgType val))
UnariseEnv -> Id -> UnariseVal -> UnariseEnv
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv UnariseEnv
rho Id
x (OutStgArg -> UnariseVal
UnaryVal OutStgArg
val)
unarise :: UniqSupply -> [StgTopBinding] -> [StgTopBinding]
unarise :: UniqSupply -> [StgTopBinding] -> [StgTopBinding]
unarise us :: UniqSupply
us binds :: [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)
mapM (UnariseEnv -> StgTopBinding -> UniqSM StgTopBinding
unariseTopBinding UnariseEnv
forall a. VarEnv a
emptyVarEnv) [StgTopBinding]
binds)
unariseTopBinding :: UnariseEnv -> StgTopBinding -> UniqSM StgTopBinding
unariseTopBinding :: UnariseEnv -> StgTopBinding -> UniqSM StgTopBinding
unariseTopBinding rho :: UnariseEnv
rho (StgTopLifted bind :: 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
-> GenStgBinding 'Vanilla -> UniqSM (GenStgBinding 'Vanilla)
unariseBinding UnariseEnv
rho GenStgBinding 'Vanilla
bind
unariseTopBinding _ bind :: StgTopBinding
bind@StgTopStringLit{} = StgTopBinding -> UniqSM StgTopBinding
forall (m :: * -> *) a. Monad m => a -> m a
return StgTopBinding
bind
unariseBinding :: UnariseEnv -> StgBinding -> UniqSM StgBinding
unariseBinding :: UnariseEnv
-> GenStgBinding 'Vanilla -> UniqSM (GenStgBinding 'Vanilla)
unariseBinding rho :: UnariseEnv
rho (StgNonRec x :: BinderP 'Vanilla
x rhs :: 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 -> GenStgRhs 'Vanilla -> UniqSM (GenStgRhs 'Vanilla)
unariseRhs UnariseEnv
rho GenStgRhs 'Vanilla
rhs
unariseBinding rho :: UnariseEnv
rho (StgRec xrhss :: [(BinderP 'Vanilla, GenStgRhs 'Vanilla)]
xrhss)
= [(Id, 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)
mapM (\(x :: Id
x, rhs :: 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 -> GenStgRhs 'Vanilla -> UniqSM (GenStgRhs 'Vanilla)
unariseRhs UnariseEnv
rho GenStgRhs 'Vanilla
rhs) [(Id, GenStgRhs 'Vanilla)]
[(BinderP 'Vanilla, GenStgRhs 'Vanilla)]
xrhss
unariseRhs :: UnariseEnv -> StgRhs -> UniqSM StgRhs
unariseRhs :: UnariseEnv -> GenStgRhs 'Vanilla -> UniqSM (GenStgRhs 'Vanilla)
unariseRhs rho :: UnariseEnv
rho (StgRhsClosure ext :: XRhsClosure 'Vanilla
ext ccs :: CostCentreStack
ccs update_flag :: UpdateFlag
update_flag args :: [BinderP 'Vanilla]
args expr :: GenStgExpr 'Vanilla
expr)
= do (rho' :: UnariseEnv
rho', args1 :: [Id]
args1) <- UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [Id])
unariseFunArgBinders UnariseEnv
rho [Id]
[BinderP 'Vanilla]
args
GenStgExpr 'Vanilla
expr' <- UnariseEnv -> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
unariseExpr UnariseEnv
rho' GenStgExpr 'Vanilla
expr
GenStgRhs 'Vanilla -> UniqSM (GenStgRhs 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
return (XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> GenStgExpr 'Vanilla
-> GenStgRhs 'Vanilla
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
ext CostCentreStack
ccs UpdateFlag
update_flag [Id]
[BinderP 'Vanilla]
args1 GenStgExpr 'Vanilla
expr')
unariseRhs rho :: UnariseEnv
rho (StgRhsCon ccs :: CostCentreStack
ccs con :: DataCon
con args :: [OutStgArg]
args)
= ASSERT(not (isUnboxedTupleCon con || isUnboxedSumCon con))
GenStgRhs 'Vanilla -> UniqSM (GenStgRhs 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
return (CostCentreStack -> DataCon -> [OutStgArg] -> GenStgRhs 'Vanilla
forall (pass :: StgPass).
CostCentreStack -> DataCon -> [OutStgArg] -> GenStgRhs pass
StgRhsCon CostCentreStack
ccs DataCon
con (UnariseEnv -> [OutStgArg] -> [OutStgArg]
unariseConArgs UnariseEnv
rho [OutStgArg]
args))
unariseExpr :: UnariseEnv -> StgExpr -> UniqSM StgExpr
unariseExpr :: UnariseEnv -> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
unariseExpr rho :: UnariseEnv
rho e :: GenStgExpr 'Vanilla
e@(StgApp f :: Id
f [])
= case UnariseEnv -> Id -> Maybe UnariseVal
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv UnariseEnv
rho Id
f of
Just (MultiVal args :: [OutStgArg]
args)
-> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
return ([OutStgArg] -> GenStgExpr 'Vanilla
mkTuple [OutStgArg]
args)
Just (UnaryVal (StgVarArg f' :: Id
f'))
-> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> [OutStgArg] -> GenStgExpr 'Vanilla
forall (pass :: StgPass). Id -> [OutStgArg] -> GenStgExpr pass
StgApp Id
f' [])
Just (UnaryVal (StgLitArg f' :: Literal
f'))
-> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
return (Literal -> GenStgExpr 'Vanilla
forall (pass :: StgPass). Literal -> GenStgExpr pass
StgLit Literal
f')
Nothing
-> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
return GenStgExpr 'Vanilla
e
unariseExpr rho :: UnariseEnv
rho e :: GenStgExpr 'Vanilla
e@(StgApp f :: Id
f args :: [OutStgArg]
args)
= GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> [OutStgArg] -> GenStgExpr 'Vanilla
forall (pass :: StgPass). Id -> [OutStgArg] -> GenStgExpr pass
StgApp Id
f' (UnariseEnv -> [OutStgArg] -> [OutStgArg]
unariseFunArgs UnariseEnv
rho [OutStgArg]
args))
where
f' :: Id
f' = case UnariseEnv -> Id -> Maybe UnariseVal
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv UnariseEnv
rho Id
f of
Just (UnaryVal (StgVarArg f' :: Id
f')) -> Id
f'
Nothing -> Id
f
err :: Maybe UnariseVal
err -> String -> SDoc -> Id
forall a. HasCallStack => String -> SDoc -> a
pprPanic "unariseExpr - app2" (GenStgExpr 'Vanilla -> SDoc
forall a. Outputable a => a -> SDoc
ppr GenStgExpr 'Vanilla
e SDoc -> SDoc -> SDoc
$$ Maybe UnariseVal -> SDoc
forall a. Outputable a => a -> SDoc
ppr Maybe UnariseVal
err)
unariseExpr _ (StgLit l :: Literal
l)
= GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
return (Literal -> GenStgExpr 'Vanilla
forall (pass :: StgPass). Literal -> GenStgExpr pass
StgLit Literal
l)
unariseExpr rho :: UnariseEnv
rho (StgConApp dc :: DataCon
dc args :: [OutStgArg]
args ty_args :: [Type]
ty_args)
| Just args' :: [OutStgArg]
args' <- UnariseEnv -> DataCon -> [OutStgArg] -> [Type] -> Maybe [OutStgArg]
unariseMulti_maybe UnariseEnv
rho DataCon
dc [OutStgArg]
args [Type]
ty_args
= GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
return ([OutStgArg] -> GenStgExpr 'Vanilla
mkTuple [OutStgArg]
args')
| Bool
otherwise
, let args' :: [OutStgArg]
args' = UnariseEnv -> [OutStgArg] -> [OutStgArg]
unariseConArgs UnariseEnv
rho [OutStgArg]
args
= GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
return (DataCon -> [OutStgArg] -> [Type] -> GenStgExpr 'Vanilla
forall (pass :: StgPass).
DataCon -> [OutStgArg] -> [Type] -> GenStgExpr pass
StgConApp DataCon
dc [OutStgArg]
args' ((OutStgArg -> Type) -> [OutStgArg] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map OutStgArg -> Type
stgArgType [OutStgArg]
args'))
unariseExpr rho :: UnariseEnv
rho (StgOpApp op :: StgOp
op args :: [OutStgArg]
args ty :: Type
ty)
= GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
return (StgOp -> [OutStgArg] -> Type -> GenStgExpr 'Vanilla
forall (pass :: StgPass).
StgOp -> [OutStgArg] -> Type -> GenStgExpr pass
StgOpApp StgOp
op (UnariseEnv -> [OutStgArg] -> [OutStgArg]
unariseFunArgs UnariseEnv
rho [OutStgArg]
args) Type
ty)
unariseExpr _ e :: GenStgExpr 'Vanilla
e@StgLam{}
= String -> SDoc -> UniqSM (GenStgExpr 'Vanilla)
forall a. HasCallStack => String -> SDoc -> a
pprPanic "unariseExpr: found lambda" (GenStgExpr 'Vanilla -> SDoc
forall a. Outputable a => a -> SDoc
ppr GenStgExpr 'Vanilla
e)
unariseExpr rho :: UnariseEnv
rho (StgCase scrut :: GenStgExpr 'Vanilla
scrut bndr :: BinderP 'Vanilla
bndr alt_ty :: AltType
alt_ty alts :: [GenStgAlt 'Vanilla]
alts)
| StgApp v :: Id
v [] <- GenStgExpr 'Vanilla
scrut
, Just (MultiVal xs :: [OutStgArg]
xs) <- UnariseEnv -> Id -> Maybe UnariseVal
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv UnariseEnv
rho Id
v
= UnariseEnv
-> [OutStgArg]
-> Id
-> AltType
-> [GenStgAlt 'Vanilla]
-> UniqSM (GenStgExpr 'Vanilla)
elimCase UnariseEnv
rho [OutStgArg]
xs Id
BinderP 'Vanilla
bndr AltType
alt_ty [GenStgAlt 'Vanilla]
alts
| StgConApp dc :: DataCon
dc args :: [OutStgArg]
args ty_args :: [Type]
ty_args <- GenStgExpr 'Vanilla
scrut
, Just args' :: [OutStgArg]
args' <- UnariseEnv -> DataCon -> [OutStgArg] -> [Type] -> Maybe [OutStgArg]
unariseMulti_maybe UnariseEnv
rho DataCon
dc [OutStgArg]
args [Type]
ty_args
= UnariseEnv
-> [OutStgArg]
-> Id
-> AltType
-> [GenStgAlt 'Vanilla]
-> UniqSM (GenStgExpr 'Vanilla)
elimCase UnariseEnv
rho [OutStgArg]
args' Id
BinderP 'Vanilla
bndr AltType
alt_ty [GenStgAlt 'Vanilla]
alts
| Bool
otherwise
= do GenStgExpr 'Vanilla
scrut' <- UnariseEnv -> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
unariseExpr UnariseEnv
rho GenStgExpr 'Vanilla
scrut
[(AltCon, [Id], GenStgExpr 'Vanilla)]
alts' <- UnariseEnv
-> AltType
-> Id
-> [GenStgAlt 'Vanilla]
-> UniqSM [GenStgAlt 'Vanilla]
unariseAlts UnariseEnv
rho AltType
alt_ty Id
BinderP 'Vanilla
bndr [GenStgAlt 'Vanilla]
alts
GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
return (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' BinderP 'Vanilla
bndr AltType
alt_ty [(AltCon, [Id], GenStgExpr 'Vanilla)]
[GenStgAlt 'Vanilla]
alts')
unariseExpr rho :: UnariseEnv
rho (StgLet ext :: XLet 'Vanilla
ext bind :: GenStgBinding 'Vanilla
bind e :: 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
-> GenStgBinding 'Vanilla -> UniqSM (GenStgBinding 'Vanilla)
unariseBinding UnariseEnv
rho GenStgBinding 'Vanilla
bind UniqSM (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> UniqSM (GenStgExpr 'Vanilla) -> UniqSM (GenStgExpr 'Vanilla)
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 rho :: UnariseEnv
rho (StgLetNoEscape ext :: XLetNoEscape 'Vanilla
ext bind :: GenStgBinding 'Vanilla
bind e :: 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
-> GenStgBinding 'Vanilla -> UniqSM (GenStgBinding 'Vanilla)
unariseBinding UnariseEnv
rho GenStgBinding 'Vanilla
bind UniqSM (GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla)
-> UniqSM (GenStgExpr 'Vanilla) -> UniqSM (GenStgExpr 'Vanilla)
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 rho :: UnariseEnv
rho (StgTick tick :: Tickish Id
tick e :: GenStgExpr 'Vanilla
e)
= Tickish Id -> GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
forall (pass :: StgPass).
Tickish Id -> GenStgExpr pass -> GenStgExpr pass
StgTick Tickish Id
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
unariseMulti_maybe :: UnariseEnv -> DataCon -> [InStgArg] -> [Type] -> Maybe [OutStgArg]
unariseMulti_maybe :: UnariseEnv -> DataCon -> [OutStgArg] -> [Type] -> Maybe [OutStgArg]
unariseMulti_maybe rho :: UnariseEnv
rho dc :: DataCon
dc args :: [OutStgArg]
args ty_args :: [Type]
ty_args
| DataCon -> Bool
isUnboxedTupleCon DataCon
dc
= [OutStgArg] -> Maybe [OutStgArg]
forall a. a -> Maybe a
Just (UnariseEnv -> [OutStgArg] -> [OutStgArg]
unariseConArgs UnariseEnv
rho [OutStgArg]
args)
| DataCon -> Bool
isUnboxedSumCon DataCon
dc
, let args1 :: [OutStgArg]
args1 = ASSERT(isSingleton args) (unariseConArgs rho args)
= [OutStgArg] -> Maybe [OutStgArg]
forall a. a -> Maybe a
Just (DataCon -> [Type] -> [OutStgArg] -> [OutStgArg]
mkUbxSum DataCon
dc [Type]
ty_args [OutStgArg]
args1)
| Bool
otherwise
= Maybe [OutStgArg]
forall a. Maybe a
Nothing
elimCase :: UnariseEnv
-> [OutStgArg]
-> InId -> AltType -> [InStgAlt] -> UniqSM OutStgExpr
elimCase :: UnariseEnv
-> [OutStgArg]
-> Id
-> AltType
-> [GenStgAlt 'Vanilla]
-> UniqSM (GenStgExpr 'Vanilla)
elimCase rho :: UnariseEnv
rho args :: [OutStgArg]
args bndr :: Id
bndr (MultiValAlt _) [(_, bndrs :: [BinderP 'Vanilla]
bndrs, rhs :: GenStgExpr 'Vanilla
rhs)]
= do let rho1 :: UnariseEnv
rho1 = UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho Id
bndr ([OutStgArg] -> UnariseVal
MultiVal [OutStgArg]
args)
rho2 :: UnariseEnv
rho2
| Id -> Bool
isUnboxedTupleBndr Id
bndr
= [Id] -> [OutStgArg] -> UnariseEnv -> UnariseEnv
mapTupleIdBinders [Id]
[BinderP 'Vanilla]
bndrs [OutStgArg]
args UnariseEnv
rho1
| Bool
otherwise
= ASSERT(isUnboxedSumBndr bndr)
if [Id] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Id]
[BinderP 'Vanilla]
bndrs then UnariseEnv
rho1
else [Id] -> [OutStgArg] -> UnariseEnv -> UnariseEnv
mapSumIdBinders [Id]
[BinderP 'Vanilla]
bndrs [OutStgArg]
args UnariseEnv
rho1
UnariseEnv -> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
unariseExpr UnariseEnv
rho2 GenStgExpr 'Vanilla
rhs
elimCase rho :: UnariseEnv
rho args :: [OutStgArg]
args bndr :: Id
bndr (MultiValAlt _) alts :: [GenStgAlt 'Vanilla]
alts
| Id -> Bool
isUnboxedSumBndr Id
bndr
= do let (tag_arg :: OutStgArg
tag_arg : real_args :: [OutStgArg]
real_args) = [OutStgArg]
args
Id
tag_bndr <- FastString -> Type -> UniqSM Id
mkId (String -> FastString
mkFastString "tag") Type
tagTy
let rho1 :: UnariseEnv
rho1 = UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho Id
bndr ([OutStgArg] -> UnariseVal
MultiVal [OutStgArg]
args)
scrut' :: GenStgExpr pass
scrut' = case OutStgArg
tag_arg of
StgVarArg v :: Id
v -> Id -> [OutStgArg] -> GenStgExpr pass
forall (pass :: StgPass). Id -> [OutStgArg] -> GenStgExpr pass
StgApp Id
v []
StgLitArg l :: Literal
l -> Literal -> GenStgExpr pass
forall (pass :: StgPass). Literal -> GenStgExpr pass
StgLit Literal
l
[(AltCon, [Id], GenStgExpr 'Vanilla)]
alts' <- UnariseEnv
-> [OutStgArg]
-> [GenStgAlt 'Vanilla]
-> UniqSM [GenStgAlt 'Vanilla]
unariseSumAlts UnariseEnv
rho1 [OutStgArg]
real_args [GenStgAlt 'Vanilla]
alts
GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
return (GenStgExpr 'Vanilla
-> BinderP 'Vanilla
-> AltType
-> [GenStgAlt 'Vanilla]
-> GenStgExpr 'Vanilla
forall (pass :: StgPass).
GenStgExpr pass
-> BinderP pass -> AltType -> [GenStgAlt pass] -> GenStgExpr pass
StgCase GenStgExpr 'Vanilla
forall (pass :: StgPass). GenStgExpr pass
scrut' Id
BinderP 'Vanilla
tag_bndr AltType
tagAltTy [(AltCon, [Id], GenStgExpr 'Vanilla)]
[GenStgAlt 'Vanilla]
alts')
elimCase _ args :: [OutStgArg]
args bndr :: Id
bndr alt_ty :: AltType
alt_ty alts :: [GenStgAlt 'Vanilla]
alts
= String -> SDoc -> UniqSM (GenStgExpr 'Vanilla)
forall a. HasCallStack => String -> SDoc -> a
pprPanic "elimCase - unhandled case"
([OutStgArg] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [OutStgArg]
args SDoc -> SDoc -> SDoc
<+> Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
bndr SDoc -> SDoc -> SDoc
<+> AltType -> SDoc
forall a. Outputable a => a -> SDoc
ppr AltType
alt_ty SDoc -> SDoc -> SDoc
$$ [(AltCon, [Id], GenStgExpr 'Vanilla)] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(AltCon, [Id], GenStgExpr 'Vanilla)]
[GenStgAlt 'Vanilla]
alts)
unariseAlts :: UnariseEnv -> AltType -> InId -> [StgAlt] -> UniqSM [StgAlt]
unariseAlts :: UnariseEnv
-> AltType
-> Id
-> [GenStgAlt 'Vanilla]
-> UniqSM [GenStgAlt 'Vanilla]
unariseAlts rho :: UnariseEnv
rho (MultiValAlt n :: Int
n) bndr :: Id
bndr [(DEFAULT, [], e :: GenStgExpr 'Vanilla
e)]
| Id -> Bool
isUnboxedTupleBndr Id
bndr
= do (rho' :: UnariseEnv
rho', ys :: [Id]
ys) <- UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseConArgBinder UnariseEnv
rho Id
bndr
GenStgExpr 'Vanilla
e' <- UnariseEnv -> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
unariseExpr UnariseEnv
rho' GenStgExpr 'Vanilla
e
[(AltCon, [Id], GenStgExpr 'Vanilla)]
-> UniqSM [(AltCon, [Id], GenStgExpr 'Vanilla)]
forall (m :: * -> *) a. Monad m => a -> m a
return [(DataCon -> AltCon
DataAlt (Boxity -> Int -> DataCon
tupleDataCon Boxity
Unboxed Int
n), [Id]
ys, GenStgExpr 'Vanilla
e')]
unariseAlts rho :: UnariseEnv
rho (MultiValAlt n :: Int
n) bndr :: Id
bndr [(DataAlt _, ys :: [BinderP 'Vanilla]
ys, e :: GenStgExpr 'Vanilla
e)]
| Id -> Bool
isUnboxedTupleBndr Id
bndr
= do (rho' :: UnariseEnv
rho', ys1 :: [Id]
ys1) <- UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [Id])
unariseConArgBinders UnariseEnv
rho [Id]
[BinderP 'Vanilla]
ys
MASSERT(ys1 `lengthIs` n)
let rho'' :: UnariseEnv
rho'' = UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho' Id
bndr ([OutStgArg] -> UnariseVal
MultiVal ((Id -> OutStgArg) -> [Id] -> [OutStgArg]
forall a b. (a -> b) -> [a] -> [b]
map Id -> OutStgArg
StgVarArg [Id]
ys1))
GenStgExpr 'Vanilla
e' <- UnariseEnv -> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
unariseExpr UnariseEnv
rho'' GenStgExpr 'Vanilla
e
[(AltCon, [Id], GenStgExpr 'Vanilla)]
-> UniqSM [(AltCon, [Id], GenStgExpr 'Vanilla)]
forall (m :: * -> *) a. Monad m => a -> m a
return [(DataCon -> AltCon
DataAlt (Boxity -> Int -> DataCon
tupleDataCon Boxity
Unboxed Int
n), [Id]
ys1, GenStgExpr 'Vanilla
e')]
unariseAlts _ (MultiValAlt _) bndr :: Id
bndr alts :: [GenStgAlt 'Vanilla]
alts
| Id -> Bool
isUnboxedTupleBndr Id
bndr
= String -> SDoc -> UniqSM [(AltCon, [Id], GenStgExpr 'Vanilla)]
forall a. HasCallStack => String -> SDoc -> a
pprPanic "unariseExpr: strange multi val alts" ([(AltCon, [Id], GenStgExpr 'Vanilla)] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(AltCon, [Id], GenStgExpr 'Vanilla)]
[GenStgAlt 'Vanilla]
alts)
unariseAlts rho :: UnariseEnv
rho (MultiValAlt _) bndr :: Id
bndr [(DEFAULT, _, rhs :: GenStgExpr 'Vanilla
rhs)]
| Id -> Bool
isUnboxedSumBndr Id
bndr
= do (rho_sum_bndrs :: UnariseEnv
rho_sum_bndrs, sum_bndrs :: [Id]
sum_bndrs) <- UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseConArgBinder UnariseEnv
rho Id
bndr
GenStgExpr 'Vanilla
rhs' <- UnariseEnv -> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
unariseExpr UnariseEnv
rho_sum_bndrs GenStgExpr 'Vanilla
rhs
[(AltCon, [Id], GenStgExpr 'Vanilla)]
-> UniqSM [(AltCon, [Id], GenStgExpr 'Vanilla)]
forall (m :: * -> *) a. Monad m => a -> m a
return [(DataCon -> AltCon
DataAlt (Boxity -> Int -> DataCon
tupleDataCon Boxity
Unboxed ([Id] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Id]
sum_bndrs)), [Id]
sum_bndrs, GenStgExpr 'Vanilla
rhs')]
unariseAlts rho :: UnariseEnv
rho (MultiValAlt _) bndr :: Id
bndr alts :: [GenStgAlt 'Vanilla]
alts
| Id -> Bool
isUnboxedSumBndr Id
bndr
= do (rho_sum_bndrs :: UnariseEnv
rho_sum_bndrs, scrt_bndrs :: [Id]
scrt_bndrs@(tag_bndr :: Id
tag_bndr : real_bndrs :: [Id]
real_bndrs)) <- UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseConArgBinder UnariseEnv
rho Id
bndr
[(AltCon, [Id], GenStgExpr 'Vanilla)]
alts' <- UnariseEnv
-> [OutStgArg]
-> [GenStgAlt 'Vanilla]
-> UniqSM [GenStgAlt 'Vanilla]
unariseSumAlts UnariseEnv
rho_sum_bndrs ((Id -> OutStgArg) -> [Id] -> [OutStgArg]
forall a b. (a -> b) -> [a] -> [b]
map Id -> OutStgArg
StgVarArg [Id]
real_bndrs) [GenStgAlt 'Vanilla]
alts
let inner_case :: GenStgExpr 'Vanilla
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 -> [OutStgArg] -> GenStgExpr 'Vanilla
forall (pass :: StgPass). Id -> [OutStgArg] -> GenStgExpr pass
StgApp Id
tag_bndr []) Id
BinderP 'Vanilla
tag_bndr AltType
tagAltTy [(AltCon, [Id], GenStgExpr 'Vanilla)]
[GenStgAlt 'Vanilla]
alts'
[(AltCon, [Id], GenStgExpr 'Vanilla)]
-> UniqSM [(AltCon, [Id], GenStgExpr 'Vanilla)]
forall (m :: * -> *) a. Monad m => a -> m a
return [ (DataCon -> AltCon
DataAlt (Boxity -> Int -> DataCon
tupleDataCon Boxity
Unboxed ([Id] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Id]
scrt_bndrs)),
[Id]
scrt_bndrs,
GenStgExpr 'Vanilla
inner_case) ]
unariseAlts rho :: UnariseEnv
rho _ _ alts :: [GenStgAlt 'Vanilla]
alts
= ((AltCon, [Id], GenStgExpr 'Vanilla)
-> UniqSM (AltCon, [Id], GenStgExpr 'Vanilla))
-> [(AltCon, [Id], GenStgExpr 'Vanilla)]
-> UniqSM [(AltCon, [Id], GenStgExpr 'Vanilla)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\alt :: (AltCon, [Id], GenStgExpr 'Vanilla)
alt -> UnariseEnv -> GenStgAlt 'Vanilla -> UniqSM (GenStgAlt 'Vanilla)
unariseAlt UnariseEnv
rho (AltCon, [Id], GenStgExpr 'Vanilla)
GenStgAlt 'Vanilla
alt) [(AltCon, [Id], GenStgExpr 'Vanilla)]
[GenStgAlt 'Vanilla]
alts
unariseAlt :: UnariseEnv -> StgAlt -> UniqSM StgAlt
unariseAlt :: UnariseEnv -> GenStgAlt 'Vanilla -> UniqSM (GenStgAlt 'Vanilla)
unariseAlt rho :: UnariseEnv
rho (con :: AltCon
con, xs :: [BinderP 'Vanilla]
xs, e :: GenStgExpr 'Vanilla
e)
= do (rho' :: UnariseEnv
rho', xs' :: [Id]
xs') <- UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [Id])
unariseConArgBinders UnariseEnv
rho [Id]
[BinderP 'Vanilla]
xs
(AltCon
con, [Id]
xs',) (GenStgExpr 'Vanilla -> (AltCon, [Id], GenStgExpr 'Vanilla))
-> UniqSM (GenStgExpr 'Vanilla)
-> UniqSM (AltCon, [Id], 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
unariseSumAlts :: UnariseEnv
-> [StgArg]
-> [StgAlt]
-> UniqSM [StgAlt]
unariseSumAlts :: UnariseEnv
-> [OutStgArg]
-> [GenStgAlt 'Vanilla]
-> UniqSM [GenStgAlt 'Vanilla]
unariseSumAlts env :: UnariseEnv
env args :: [OutStgArg]
args alts :: [GenStgAlt 'Vanilla]
alts
= do [(AltCon, [Id], GenStgExpr 'Vanilla)]
alts' <- ((AltCon, [Id], GenStgExpr 'Vanilla)
-> UniqSM (AltCon, [Id], GenStgExpr 'Vanilla))
-> [(AltCon, [Id], GenStgExpr 'Vanilla)]
-> UniqSM [(AltCon, [Id], GenStgExpr 'Vanilla)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (UnariseEnv
-> [OutStgArg] -> GenStgAlt 'Vanilla -> UniqSM (GenStgAlt 'Vanilla)
unariseSumAlt UnariseEnv
env [OutStgArg]
args) [(AltCon, [Id], GenStgExpr 'Vanilla)]
[GenStgAlt 'Vanilla]
alts
[(AltCon, [Id], GenStgExpr 'Vanilla)]
-> UniqSM [(AltCon, [Id], GenStgExpr 'Vanilla)]
forall (m :: * -> *) a. Monad m => a -> m a
return ([GenStgAlt 'Vanilla] -> [GenStgAlt 'Vanilla]
mkDefaultLitAlt [(AltCon, [Id], GenStgExpr 'Vanilla)]
[GenStgAlt 'Vanilla]
alts')
unariseSumAlt :: UnariseEnv
-> [StgArg]
-> StgAlt
-> UniqSM StgAlt
unariseSumAlt :: UnariseEnv
-> [OutStgArg] -> GenStgAlt 'Vanilla -> UniqSM (GenStgAlt 'Vanilla)
unariseSumAlt rho :: UnariseEnv
rho _ (DEFAULT, _, e :: GenStgExpr 'Vanilla
e)
= ( AltCon
DEFAULT, [], ) (GenStgExpr 'Vanilla -> (AltCon, [Id], GenStgExpr 'Vanilla))
-> UniqSM (GenStgExpr 'Vanilla)
-> UniqSM (AltCon, [Id], 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
unariseSumAlt rho :: UnariseEnv
rho args :: [OutStgArg]
args (DataAlt sumCon :: DataCon
sumCon, bs :: [BinderP 'Vanilla]
bs, e :: GenStgExpr 'Vanilla
e)
= do let rho' :: UnariseEnv
rho' = [Id] -> [OutStgArg] -> UnariseEnv -> UnariseEnv
mapSumIdBinders [Id]
[BinderP 'Vanilla]
bs [OutStgArg]
args UnariseEnv
rho
GenStgExpr 'Vanilla
e' <- UnariseEnv -> GenStgExpr 'Vanilla -> UniqSM (GenStgExpr 'Vanilla)
unariseExpr UnariseEnv
rho' GenStgExpr 'Vanilla
e
(AltCon, [Id], GenStgExpr 'Vanilla)
-> UniqSM (AltCon, [Id], GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
return ( Literal -> AltCon
LitAlt (LitNumType -> Integer -> Type -> Literal
LitNumber LitNumType
LitNumInt (Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (DataCon -> Int
dataConTag DataCon
sumCon)) Type
intPrimTy), [], GenStgExpr 'Vanilla
e' )
unariseSumAlt _ scrt :: [OutStgArg]
scrt alt :: GenStgAlt 'Vanilla
alt
= String -> SDoc -> UniqSM (AltCon, [Id], GenStgExpr 'Vanilla)
forall a. HasCallStack => String -> SDoc -> a
pprPanic "unariseSumAlt" ([OutStgArg] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [OutStgArg]
scrt SDoc -> SDoc -> SDoc
$$ (AltCon, [Id], GenStgExpr 'Vanilla) -> SDoc
forall a. Outputable a => a -> SDoc
ppr (AltCon, [Id], GenStgExpr 'Vanilla)
GenStgAlt 'Vanilla
alt)
mapTupleIdBinders
:: [InId]
-> [OutStgArg]
-> UnariseEnv
-> UnariseEnv
mapTupleIdBinders :: [Id] -> [OutStgArg] -> UnariseEnv -> UnariseEnv
mapTupleIdBinders ids :: [Id]
ids args0 :: [OutStgArg]
args0 rho0 :: UnariseEnv
rho0
= ASSERT(not (any (isVoidTy . stgArgType) args0))
let
ids_unarised :: [(Id, [PrimRep])]
ids_unarised :: [(Id, [PrimRep])]
ids_unarised = (Id -> (Id, [PrimRep])) -> [Id] -> [(Id, [PrimRep])]
forall a b. (a -> b) -> [a] -> [b]
map (\id :: Id
id -> (Id
id, HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
typePrimRep (Id -> Type
idType Id
id))) [Id]
ids
map_ids :: UnariseEnv -> [(Id, [PrimRep])] -> [StgArg] -> UnariseEnv
map_ids :: UnariseEnv -> [(Id, [PrimRep])] -> [OutStgArg] -> UnariseEnv
map_ids rho :: UnariseEnv
rho [] _ = UnariseEnv
rho
map_ids rho :: UnariseEnv
rho ((x :: Id
x, x_reps :: [PrimRep]
x_reps) : xs :: [(Id, [PrimRep])]
xs) args :: [OutStgArg]
args =
let
x_arity :: Int
x_arity = [PrimRep] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [PrimRep]
x_reps
(x_args :: [OutStgArg]
x_args, args' :: [OutStgArg]
args') =
ASSERT(args `lengthAtLeast` x_arity)
Int -> [OutStgArg] -> ([OutStgArg], [OutStgArg])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
x_arity [OutStgArg]
args
rho' :: UnariseEnv
rho'
| Int
x_arity Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 1
= ASSERT(x_args `lengthIs` 1)
UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho Id
x (OutStgArg -> UnariseVal
UnaryVal ([OutStgArg] -> OutStgArg
forall a. [a] -> a
head [OutStgArg]
x_args))
| Bool
otherwise
= UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho Id
x ([OutStgArg] -> UnariseVal
MultiVal [OutStgArg]
x_args)
in
UnariseEnv -> [(Id, [PrimRep])] -> [OutStgArg] -> UnariseEnv
map_ids UnariseEnv
rho' [(Id, [PrimRep])]
xs [OutStgArg]
args'
in
UnariseEnv -> [(Id, [PrimRep])] -> [OutStgArg] -> UnariseEnv
map_ids UnariseEnv
rho0 [(Id, [PrimRep])]
ids_unarised [OutStgArg]
args0
mapSumIdBinders
:: [InId]
-> [OutStgArg]
-> UnariseEnv
-> UnariseEnv
mapSumIdBinders :: [Id] -> [OutStgArg] -> UnariseEnv -> UnariseEnv
mapSumIdBinders [id :: Id
id] args :: [OutStgArg]
args rho0 :: UnariseEnv
rho0
= ASSERT(not (any (isVoidTy . stgArgType) args))
let
arg_slots :: [SlotTy]
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
$ (OutStgArg -> [PrimRep]) -> [OutStgArg] -> [PrimRep]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
typePrimRep (Type -> [PrimRep])
-> (OutStgArg -> Type) -> OutStgArg -> [PrimRep]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OutStgArg -> Type
stgArgType) [OutStgArg]
args
id_slots :: [SlotTy]
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
$ HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
typePrimRep (Id -> Type
idType Id
id)
layout1 :: [Int]
layout1 = [SlotTy] -> [SlotTy] -> [Int]
layoutUbxSum [SlotTy]
arg_slots [SlotTy]
id_slots
in
if Id -> Bool
isMultiValBndr Id
id
then UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho0 Id
id ([OutStgArg] -> UnariseVal
MultiVal [ [OutStgArg]
args [OutStgArg] -> Int -> OutStgArg
forall a. [a] -> Int -> a
!! Int
i | Int
i <- [Int]
layout1 ])
else ASSERT(layout1 `lengthIs` 1)
UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho0 Id
id (OutStgArg -> UnariseVal
UnaryVal ([OutStgArg]
args [OutStgArg] -> Int -> OutStgArg
forall a. [a] -> Int -> a
!! [Int] -> Int
forall a. [a] -> a
head [Int]
layout1))
mapSumIdBinders ids :: [Id]
ids sum_args :: [OutStgArg]
sum_args _
= String -> SDoc -> UnariseEnv
forall a. HasCallStack => String -> SDoc -> a
pprPanic "mapSumIdBinders" ([Id] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Id]
ids SDoc -> SDoc -> SDoc
$$ [OutStgArg] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [OutStgArg]
sum_args)
mkUbxSum
:: DataCon
-> [Type]
-> [OutStgArg]
-> [OutStgArg]
mkUbxSum :: DataCon -> [Type] -> [OutStgArg] -> [OutStgArg]
mkUbxSum dc :: DataCon
dc ty_args :: [Type]
ty_args args0 :: [OutStgArg]
args0
= let
(_ : sum_slots :: [SlotTy]
sum_slots) = [[PrimRep]] -> [SlotTy]
ubxSumRepType ((Type -> [PrimRep]) -> [Type] -> [[PrimRep]]
forall a b. (a -> b) -> [a] -> [b]
map HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
typePrimRep [Type]
ty_args)
tag :: Int
tag = DataCon -> Int
dataConTag DataCon
dc
layout' :: [Int]
layout' = [SlotTy] -> [SlotTy] -> [Int]
layoutUbxSum [SlotTy]
sum_slots ((OutStgArg -> Maybe SlotTy) -> [OutStgArg] -> [SlotTy]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (Type -> Maybe SlotTy
typeSlotTy (Type -> Maybe SlotTy)
-> (OutStgArg -> Type) -> OutStgArg -> Maybe SlotTy
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OutStgArg -> Type
stgArgType) [OutStgArg]
args0)
tag_arg :: OutStgArg
tag_arg = Literal -> OutStgArg
StgLitArg (LitNumType -> Integer -> Type -> Literal
LitNumber LitNumType
LitNumInt (Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
tag) Type
intPrimTy)
arg_idxs :: IntMap OutStgArg
arg_idxs = [(Int, OutStgArg)] -> IntMap OutStgArg
forall a. [(Int, a)] -> IntMap a
IM.fromList (String -> [Int] -> [OutStgArg] -> [(Int, OutStgArg)]
forall a b. String -> [a] -> [b] -> [(a, b)]
zipEqual "mkUbxSum" [Int]
layout' [OutStgArg]
args0)
mkTupArgs :: Int -> [SlotTy] -> IM.IntMap StgArg -> [StgArg]
mkTupArgs :: Int -> [SlotTy] -> IntMap OutStgArg -> [OutStgArg]
mkTupArgs _ [] _
= []
mkTupArgs arg_idx :: Int
arg_idx (slot :: SlotTy
slot : slots_left :: [SlotTy]
slots_left) arg_map :: IntMap OutStgArg
arg_map
| Just stg_arg :: OutStgArg
stg_arg <- Int -> IntMap OutStgArg -> Maybe OutStgArg
forall a. Int -> IntMap a -> Maybe a
IM.lookup Int
arg_idx IntMap OutStgArg
arg_map
= OutStgArg
stg_arg OutStgArg -> [OutStgArg] -> [OutStgArg]
forall a. a -> [a] -> [a]
: Int -> [SlotTy] -> IntMap OutStgArg -> [OutStgArg]
mkTupArgs (Int
arg_idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) [SlotTy]
slots_left IntMap OutStgArg
arg_map
| Bool
otherwise
= SlotTy -> OutStgArg
slotRubbishArg SlotTy
slot OutStgArg -> [OutStgArg] -> [OutStgArg]
forall a. a -> [a] -> [a]
: Int -> [SlotTy] -> IntMap OutStgArg -> [OutStgArg]
mkTupArgs (Int
arg_idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) [SlotTy]
slots_left IntMap OutStgArg
arg_map
slotRubbishArg :: SlotTy -> StgArg
slotRubbishArg :: SlotTy -> OutStgArg
slotRubbishArg PtrSlot = Id -> OutStgArg
StgVarArg Id
aBSENT_SUM_FIELD_ERROR_ID
slotRubbishArg WordSlot = Literal -> OutStgArg
StgLitArg (LitNumType -> Integer -> Type -> Literal
LitNumber LitNumType
LitNumWord 0 Type
wordPrimTy)
slotRubbishArg Word64Slot = Literal -> OutStgArg
StgLitArg (LitNumType -> Integer -> Type -> Literal
LitNumber LitNumType
LitNumWord64 0 Type
word64PrimTy)
slotRubbishArg FloatSlot = Literal -> OutStgArg
StgLitArg (Rational -> Literal
LitFloat 0)
slotRubbishArg DoubleSlot = Literal -> OutStgArg
StgLitArg (Rational -> Literal
LitDouble 0)
in
OutStgArg
tag_arg OutStgArg -> [OutStgArg] -> [OutStgArg]
forall a. a -> [a] -> [a]
: Int -> [SlotTy] -> IntMap OutStgArg -> [OutStgArg]
mkTupArgs 0 [SlotTy]
sum_slots IntMap OutStgArg
arg_idxs
unariseArgBinder
:: Bool
-> UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseArgBinder :: Bool -> UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id])
unariseArgBinder is_con_arg :: Bool
is_con_arg rho :: UnariseEnv
rho x :: 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 (m :: * -> *) a. Monad m => a -> m a
return (UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho Id
x ([OutStgArg] -> UnariseVal
MultiVal []), [])
| Bool
otherwise
-> (UnariseEnv, [Id]) -> UniqSM (UnariseEnv, [Id])
forall (m :: * -> *) a. Monad m => a -> m a
return (UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho Id
x ([OutStgArg] -> UnariseVal
MultiVal []), [Id
voidArgId])
[rep :: PrimRep
rep]
| Type -> Bool
isUnboxedSumType (Id -> Type
idType Id
x) Bool -> Bool -> Bool
|| Type -> Bool
isUnboxedTupleType (Id -> Type
idType Id
x)
-> do Id
x' <- FastString -> Type -> UniqSM Id
mkId (String -> FastString
mkFastString "us") (PrimRep -> Type
primRepToType PrimRep
rep)
(UnariseEnv, [Id]) -> UniqSM (UnariseEnv, [Id])
forall (m :: * -> *) a. Monad m => a -> m a
return (UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho Id
x ([OutStgArg] -> UnariseVal
MultiVal [Id -> OutStgArg
StgVarArg Id
x']), [Id
x'])
| Bool
otherwise
-> (UnariseEnv, [Id]) -> UniqSM (UnariseEnv, [Id])
forall (m :: * -> *) a. Monad m => a -> m a
return (UnariseEnv
rho, [Id
x])
reps :: [PrimRep]
reps -> do
[Id]
xs <- FastString -> [Type] -> UniqSM [Id]
mkIds (String -> FastString
mkFastString "us") ((PrimRep -> Type) -> [PrimRep] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map PrimRep -> Type
primRepToType [PrimRep]
reps)
(UnariseEnv, [Id]) -> UniqSM (UnariseEnv, [Id])
forall (m :: * -> *) a. Monad m => a -> m a
return (UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho UnariseEnv
rho Id
x ([OutStgArg] -> UnariseVal
MultiVal ((Id -> OutStgArg) -> [Id] -> [OutStgArg]
forall a b. (a -> b) -> [a] -> [b]
map Id -> OutStgArg
StgVarArg [Id]
xs)), [Id]
xs)
unariseFunArg :: UnariseEnv -> StgArg -> [StgArg]
unariseFunArg :: UnariseEnv -> OutStgArg -> [OutStgArg]
unariseFunArg rho :: UnariseEnv
rho (StgVarArg x :: Id
x) =
case UnariseEnv -> Id -> Maybe UnariseVal
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv UnariseEnv
rho Id
x of
Just (MultiVal []) -> [OutStgArg
voidArg]
Just (MultiVal as :: [OutStgArg]
as) -> [OutStgArg]
as
Just (UnaryVal arg :: OutStgArg
arg) -> [OutStgArg
arg]
Nothing -> [Id -> OutStgArg
StgVarArg Id
x]
unariseFunArg _ arg :: OutStgArg
arg = [OutStgArg
arg]
unariseFunArgs :: UnariseEnv -> [StgArg] -> [StgArg]
unariseFunArgs :: UnariseEnv -> [OutStgArg] -> [OutStgArg]
unariseFunArgs = (OutStgArg -> [OutStgArg]) -> [OutStgArg] -> [OutStgArg]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((OutStgArg -> [OutStgArg]) -> [OutStgArg] -> [OutStgArg])
-> (UnariseEnv -> OutStgArg -> [OutStgArg])
-> UnariseEnv
-> [OutStgArg]
-> [OutStgArg]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnariseEnv -> OutStgArg -> [OutStgArg]
unariseFunArg
unariseFunArgBinders :: UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [Id])
unariseFunArgBinders :: UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [Id])
unariseFunArgBinders rho :: UnariseEnv
rho xs :: [Id]
xs = ([[Id]] -> [Id]) -> (UnariseEnv, [[Id]]) -> (UnariseEnv, [Id])
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 :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [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 -> OutStgArg -> [OutStgArg]
unariseConArg rho :: UnariseEnv
rho (StgVarArg x :: Id
x) =
case UnariseEnv -> Id -> Maybe UnariseVal
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv UnariseEnv
rho Id
x of
Just (UnaryVal arg :: OutStgArg
arg) -> [OutStgArg
arg]
Just (MultiVal as :: [OutStgArg]
as) -> [OutStgArg]
as
Nothing
| Type -> Bool
isVoidTy (Id -> Type
idType Id
x) -> []
| Bool
otherwise -> [Id -> OutStgArg
StgVarArg Id
x]
unariseConArg _ arg :: OutStgArg
arg@(StgLitArg lit :: Literal
lit) =
ASSERT(not (isVoidTy (literalType lit)))
[OutStgArg
arg]
unariseConArgs :: UnariseEnv -> [InStgArg] -> [OutStgArg]
unariseConArgs :: UnariseEnv -> [OutStgArg] -> [OutStgArg]
unariseConArgs = (OutStgArg -> [OutStgArg]) -> [OutStgArg] -> [OutStgArg]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((OutStgArg -> [OutStgArg]) -> [OutStgArg] -> [OutStgArg])
-> (UnariseEnv -> OutStgArg -> [OutStgArg])
-> UnariseEnv
-> [OutStgArg]
-> [OutStgArg]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnariseEnv -> OutStgArg -> [OutStgArg]
unariseConArg
unariseConArgBinders :: UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [Id])
unariseConArgBinders :: UnariseEnv -> [Id] -> UniqSM (UnariseEnv, [Id])
unariseConArgBinders rho :: UnariseEnv
rho xs :: [Id]
xs = ([[Id]] -> [Id]) -> (UnariseEnv, [[Id]]) -> (UnariseEnv, [Id])
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 :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [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 -> [UnaryType] -> UniqSM [Id]
mkIds :: FastString -> [Type] -> UniqSM [Id]
mkIds fs :: FastString
fs tys :: [Type]
tys = (Type -> UniqSM Id) -> [Type] -> UniqSM [Id]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (FastString -> Type -> UniqSM Id
mkId FastString
fs) [Type]
tys
mkId :: FastString -> UnaryType -> UniqSM Id
mkId :: FastString -> Type -> UniqSM Id
mkId = FastString -> Type -> UniqSM Id
forall (m :: * -> *). MonadUnique m => FastString -> Type -> m Id
mkSysLocalOrCoVarM
isMultiValBndr :: Id -> Bool
isMultiValBndr :: Id -> Bool
isMultiValBndr id :: Id
id
| [_] <- 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 :: [OutStgArg] -> GenStgExpr 'Vanilla
mkTuple args :: [OutStgArg]
args = DataCon -> [OutStgArg] -> [Type] -> GenStgExpr 'Vanilla
forall (pass :: StgPass).
DataCon -> [OutStgArg] -> [Type] -> GenStgExpr pass
StgConApp (Boxity -> Int -> DataCon
tupleDataCon Boxity
Unboxed ([OutStgArg] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [OutStgArg]
args)) [OutStgArg]
args ((OutStgArg -> Type) -> [OutStgArg] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map OutStgArg -> Type
stgArgType [OutStgArg]
args)
tagAltTy :: AltType
tagAltTy :: AltType
tagAltTy = PrimRep -> AltType
PrimAlt PrimRep
IntRep
tagTy :: Type
tagTy :: Type
tagTy = Type
intPrimTy
voidArg :: StgArg
voidArg :: OutStgArg
voidArg = Id -> OutStgArg
StgVarArg Id
voidPrimId
mkDefaultLitAlt :: [StgAlt] -> [StgAlt]
mkDefaultLitAlt :: [GenStgAlt 'Vanilla] -> [GenStgAlt 'Vanilla]
mkDefaultLitAlt [] = String -> SDoc -> [(AltCon, [Id], GenStgExpr 'Vanilla)]
forall a. HasCallStack => String -> SDoc -> a
pprPanic "elimUbxSumExpr.mkDefaultAlt" (String -> SDoc
text "Empty alts")
mkDefaultLitAlt alts :: [GenStgAlt 'Vanilla]
alts@((DEFAULT, _, _) : _) = [GenStgAlt 'Vanilla]
alts
mkDefaultLitAlt ((LitAlt{}, [], rhs :: GenStgExpr 'Vanilla
rhs) : alts :: [GenStgAlt 'Vanilla]
alts) = (AltCon
DEFAULT, [], GenStgExpr 'Vanilla
rhs) (AltCon, [Id], GenStgExpr 'Vanilla)
-> [(AltCon, [Id], GenStgExpr 'Vanilla)]
-> [(AltCon, [Id], GenStgExpr 'Vanilla)]
forall a. a -> [a] -> [a]
: [(AltCon, [Id], GenStgExpr 'Vanilla)]
[GenStgAlt 'Vanilla]
alts
mkDefaultLitAlt alts :: [GenStgAlt 'Vanilla]
alts = String -> SDoc -> [(AltCon, [Id], GenStgExpr 'Vanilla)]
forall a. HasCallStack => String -> SDoc -> a
pprPanic "mkDefaultLitAlt" (String -> SDoc
text "Not a lit alt:" SDoc -> SDoc -> SDoc
<+> [(AltCon, [Id], GenStgExpr 'Vanilla)] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(AltCon, [Id], GenStgExpr 'Vanilla)]
[GenStgAlt 'Vanilla]
alts)