module GHC.Core.Opt.Simplify.Utils (
mkLam, mkCase, prepareAlts, tryEtaExpandRhs,
preInlineUnconditionally, postInlineUnconditionally,
activeUnfolding, activeRule,
getUnfoldingInRuleMatch,
simplEnvForGHCi, updModeForStableUnfoldings, updModeForRules,
BindContext(..), bindContextLevel,
SimplCont(..), DupFlag(..), StaticEnv,
isSimplified, contIsStop,
contIsDupable, contResultType, contHoleType, contHoleScaling,
contIsTrivial, contArgs,
countArgs,
mkBoringStop, mkRhsStop, mkLazyArgStop, contIsRhsOrArg,
interestingCallContext,
ArgInfo(..), ArgSpec(..), mkArgInfo,
addValArgTo, addCastTo, addTyArgTo,
argInfoExpr, argInfoAppArgs, pushSimplifiedArgs,
isStrictArgInfo, lazyArgContext,
abstractFloats,
isExitJoinId
) where
import GHC.Prelude
import GHC.Driver.Session
import GHC.Core
import GHC.Types.Literal ( isLitRubbish )
import GHC.Core.Opt.Simplify.Env
import GHC.Core.Opt.Monad ( SimplMode(..), Tick(..) )
import qualified GHC.Core.Subst
import GHC.Core.Ppr
import GHC.Core.TyCo.Ppr ( pprParendType )
import GHC.Core.FVs
import GHC.Core.Utils
import GHC.Core.Opt.Arity
import GHC.Core.Unfold
import GHC.Core.Unfold.Make
import GHC.Core.Opt.Simplify.Monad
import GHC.Core.Type hiding( substTy )
import GHC.Core.Coercion hiding( substCo )
import GHC.Core.DataCon ( dataConWorkId, isNullaryRepDataCon )
import GHC.Core.Multiplicity
import GHC.Core.Opt.ConstantFold
import GHC.Types.Name
import GHC.Types.Id
import GHC.Types.Id.Info
import GHC.Types.Tickish
import GHC.Types.Demand
import GHC.Types.Var.Set
import GHC.Types.Basic
import GHC.Data.OrdList ( isNilOL )
import GHC.Data.FastString ( fsLit )
import GHC.Utils.Misc
import GHC.Utils.Monad
import GHC.Utils.Outputable
import GHC.Utils.Logger
import GHC.Utils.Panic
import GHC.Utils.Panic.Plain
import GHC.Utils.Trace
import Control.Monad ( when )
import Data.List ( sortBy )
data BindContext
= BC_Let
TopLevelFlag RecFlag
| BC_Join
SimplCont
bindContextLevel :: BindContext -> TopLevelFlag
bindContextLevel :: BindContext -> TopLevelFlag
bindContextLevel (BC_Let TopLevelFlag
top_lvl RecFlag
_) = TopLevelFlag
top_lvl
bindContextLevel (BC_Join {}) = TopLevelFlag
NotTopLevel
data SimplCont
= Stop
OutType
CallCtxt
| CastIt
OutCoercion
SimplCont
| ApplyToVal
{ SimplCont -> DupFlag
sc_dup :: DupFlag
, SimplCont -> OutType
sc_hole_ty :: OutType
, SimplCont -> Expr Id
sc_arg :: InExpr
, SimplCont -> StaticEnv
sc_env :: StaticEnv
, SimplCont -> SimplCont
sc_cont :: SimplCont }
| ApplyToTy
{ SimplCont -> OutType
sc_arg_ty :: OutType
, sc_hole_ty :: OutType
, sc_cont :: SimplCont }
| Select
{ sc_dup :: DupFlag
, SimplCont -> Id
sc_bndr :: InId
, SimplCont -> [InAlt]
sc_alts :: [InAlt]
, sc_env :: StaticEnv
, sc_cont :: SimplCont }
| StrictBind
{ sc_dup :: DupFlag
, sc_bndr :: InId
, SimplCont -> Expr Id
sc_body :: InExpr
, sc_env :: StaticEnv
, sc_cont :: SimplCont }
| StrictArg
{ sc_dup :: DupFlag
, SimplCont -> ArgInfo
sc_fun :: ArgInfo
, SimplCont -> OutType
sc_fun_ty :: OutType
, sc_cont :: SimplCont }
| TickIt
CoreTickish
SimplCont
type StaticEnv = SimplEnv
data DupFlag = NoDup
| Simplified
| OkToDup
isSimplified :: DupFlag -> Bool
isSimplified :: DupFlag -> Bool
isSimplified DupFlag
NoDup = Bool
False
isSimplified DupFlag
_ = Bool
True
perhapsSubstTy :: DupFlag -> StaticEnv -> Type -> Type
perhapsSubstTy :: DupFlag -> StaticEnv -> OutType -> OutType
perhapsSubstTy DupFlag
dup StaticEnv
env OutType
ty
| DupFlag -> Bool
isSimplified DupFlag
dup = OutType
ty
| Bool
otherwise = StaticEnv -> OutType -> OutType
substTy StaticEnv
env OutType
ty
instance Outputable DupFlag where
ppr :: DupFlag -> SDoc
ppr DupFlag
OkToDup = String -> SDoc
text String
"ok"
ppr DupFlag
NoDup = String -> SDoc
text String
"nodup"
ppr DupFlag
Simplified = String -> SDoc
text String
"simpl"
instance Outputable SimplCont where
ppr :: SimplCont -> SDoc
ppr (Stop OutType
ty CallCtxt
interesting) = String -> SDoc
text String
"Stop" SDoc -> SDoc -> SDoc
<> SDoc -> SDoc
brackets (CallCtxt -> SDoc
forall a. Outputable a => a -> SDoc
ppr CallCtxt
interesting) SDoc -> SDoc -> SDoc
<+> OutType -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutType
ty
ppr (CastIt OutCoercion
co SimplCont
cont ) = (String -> SDoc
text String
"CastIt" SDoc -> SDoc -> SDoc
<+> OutCoercion -> SDoc
pprOptCo OutCoercion
co) SDoc -> SDoc -> SDoc
$$ SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
cont
ppr (TickIt CoreTickish
t SimplCont
cont) = (String -> SDoc
text String
"TickIt" SDoc -> SDoc -> SDoc
<+> CoreTickish -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreTickish
t) SDoc -> SDoc -> SDoc
$$ SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
cont
ppr (ApplyToTy { sc_arg_ty :: SimplCont -> OutType
sc_arg_ty = OutType
ty, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont })
= (String -> SDoc
text String
"ApplyToTy" SDoc -> SDoc -> SDoc
<+> OutType -> SDoc
pprParendType OutType
ty) SDoc -> SDoc -> SDoc
$$ SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
cont
ppr (ApplyToVal { sc_arg :: SimplCont -> Expr Id
sc_arg = Expr Id
arg, sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
dup, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont, sc_hole_ty :: SimplCont -> OutType
sc_hole_ty = OutType
hole_ty })
= (SDoc -> Arity -> SDoc -> SDoc
hang (String -> SDoc
text String
"ApplyToVal" SDoc -> SDoc -> SDoc
<+> DupFlag -> SDoc
forall a. Outputable a => a -> SDoc
ppr DupFlag
dup SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"hole" SDoc -> SDoc -> SDoc
<+> OutType -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutType
hole_ty)
Arity
2 (Expr Id -> SDoc
forall b. OutputableBndr b => Expr b -> SDoc
pprParendExpr Expr Id
arg))
SDoc -> SDoc -> SDoc
$$ SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
cont
ppr (StrictBind { sc_bndr :: SimplCont -> Id
sc_bndr = Id
b, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont })
= (String -> SDoc
text String
"StrictBind" SDoc -> SDoc -> SDoc
<+> Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
b) SDoc -> SDoc -> SDoc
$$ SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
cont
ppr (StrictArg { sc_fun :: SimplCont -> ArgInfo
sc_fun = ArgInfo
ai, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont })
= (String -> SDoc
text String
"StrictArg" SDoc -> SDoc -> SDoc
<+> Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr (ArgInfo -> Id
ai_fun ArgInfo
ai)) SDoc -> SDoc -> SDoc
$$ SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
cont
ppr (Select { sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
dup, sc_bndr :: SimplCont -> Id
sc_bndr = Id
bndr, sc_alts :: SimplCont -> [InAlt]
sc_alts = [InAlt]
alts, sc_env :: SimplCont -> StaticEnv
sc_env = StaticEnv
se, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont })
= (String -> SDoc
text String
"Select" SDoc -> SDoc -> SDoc
<+> DupFlag -> SDoc
forall a. Outputable a => a -> SDoc
ppr DupFlag
dup SDoc -> SDoc -> SDoc
<+> Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
bndr) SDoc -> SDoc -> SDoc
$$
SDoc -> SDoc
whenPprDebug (Arity -> SDoc -> SDoc
nest Arity
2 (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
vcat [TvSubstEnv -> SDoc
forall a. Outputable a => a -> SDoc
ppr (StaticEnv -> TvSubstEnv
seTvSubst StaticEnv
se), [InAlt] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [InAlt]
alts]) SDoc -> SDoc -> SDoc
$$ SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
cont
data ArgInfo
= ArgInfo {
ArgInfo -> Id
ai_fun :: OutId,
ArgInfo -> [ArgSpec]
ai_args :: [ArgSpec],
ArgInfo -> FunRules
ai_rules :: FunRules,
ArgInfo -> Bool
ai_encl :: Bool,
ArgInfo -> [Demand]
ai_dmds :: [Demand],
ArgInfo -> [Arity]
ai_discs :: [Int]
}
data ArgSpec
= ValArg { ArgSpec -> Demand
as_dmd :: Demand
, ArgSpec -> Expr Id
as_arg :: OutExpr
, ArgSpec -> OutType
as_hole_ty :: OutType }
| TyArg { ArgSpec -> OutType
as_arg_ty :: OutType
, as_hole_ty :: OutType }
| CastBy OutCoercion
instance Outputable ArgInfo where
ppr :: ArgInfo -> SDoc
ppr (ArgInfo { ai_fun :: ArgInfo -> Id
ai_fun = Id
fun, ai_args :: ArgInfo -> [ArgSpec]
ai_args = [ArgSpec]
args, ai_dmds :: ArgInfo -> [Demand]
ai_dmds = [Demand]
dmds })
= String -> SDoc
text String
"ArgInfo" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
braces
([SDoc] -> SDoc
sep [ String -> SDoc
text String
"fun =" SDoc -> SDoc -> SDoc
<+> Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
fun
, String -> SDoc
text String
"dmds =" SDoc -> SDoc -> SDoc
<+> [Demand] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Demand]
dmds
, String -> SDoc
text String
"args =" SDoc -> SDoc -> SDoc
<+> [ArgSpec] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [ArgSpec]
args ])
instance Outputable ArgSpec where
ppr :: ArgSpec -> SDoc
ppr (ValArg { as_arg :: ArgSpec -> Expr Id
as_arg = Expr Id
arg }) = String -> SDoc
text String
"ValArg" SDoc -> SDoc -> SDoc
<+> Expr Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Expr Id
arg
ppr (TyArg { as_arg_ty :: ArgSpec -> OutType
as_arg_ty = OutType
ty }) = String -> SDoc
text String
"TyArg" SDoc -> SDoc -> SDoc
<+> OutType -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutType
ty
ppr (CastBy OutCoercion
c) = String -> SDoc
text String
"CastBy" SDoc -> SDoc -> SDoc
<+> OutCoercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutCoercion
c
addValArgTo :: ArgInfo -> OutExpr -> OutType -> ArgInfo
addValArgTo :: ArgInfo -> Expr Id -> OutType -> ArgInfo
addValArgTo ArgInfo
ai Expr Id
arg OutType
hole_ty
| ArgInfo { ai_dmds :: ArgInfo -> [Demand]
ai_dmds = Demand
dmd:[Demand]
dmds, ai_discs :: ArgInfo -> [Arity]
ai_discs = Arity
_:[Arity]
discs, ai_rules :: ArgInfo -> FunRules
ai_rules = FunRules
rules } <- ArgInfo
ai
, let arg_spec :: ArgSpec
arg_spec = ValArg { as_arg :: Expr Id
as_arg = Expr Id
arg, as_hole_ty :: OutType
as_hole_ty = OutType
hole_ty, as_dmd :: Demand
as_dmd = Demand
dmd }
= ArgInfo
ai { ai_args :: [ArgSpec]
ai_args = ArgSpec
arg_spec ArgSpec -> [ArgSpec] -> [ArgSpec]
forall a. a -> [a] -> [a]
: ArgInfo -> [ArgSpec]
ai_args ArgInfo
ai
, ai_dmds :: [Demand]
ai_dmds = [Demand]
dmds
, ai_discs :: [Arity]
ai_discs = [Arity]
discs
, ai_rules :: FunRules
ai_rules = FunRules -> FunRules
decRules FunRules
rules }
| Bool
otherwise
= String -> SDoc -> ArgInfo
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"addValArgTo" (ArgInfo -> SDoc
forall a. Outputable a => a -> SDoc
ppr ArgInfo
ai SDoc -> SDoc -> SDoc
$$ Expr Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Expr Id
arg)
addTyArgTo :: ArgInfo -> OutType -> OutType -> ArgInfo
addTyArgTo :: ArgInfo -> OutType -> OutType -> ArgInfo
addTyArgTo ArgInfo
ai OutType
arg_ty OutType
hole_ty = ArgInfo
ai { ai_args :: [ArgSpec]
ai_args = ArgSpec
arg_spec ArgSpec -> [ArgSpec] -> [ArgSpec]
forall a. a -> [a] -> [a]
: ArgInfo -> [ArgSpec]
ai_args ArgInfo
ai
, ai_rules :: FunRules
ai_rules = FunRules -> FunRules
decRules (ArgInfo -> FunRules
ai_rules ArgInfo
ai) }
where
arg_spec :: ArgSpec
arg_spec = TyArg { as_arg_ty :: OutType
as_arg_ty = OutType
arg_ty, as_hole_ty :: OutType
as_hole_ty = OutType
hole_ty }
addCastTo :: ArgInfo -> OutCoercion -> ArgInfo
addCastTo :: ArgInfo -> OutCoercion -> ArgInfo
addCastTo ArgInfo
ai OutCoercion
co = ArgInfo
ai { ai_args :: [ArgSpec]
ai_args = OutCoercion -> ArgSpec
CastBy OutCoercion
co ArgSpec -> [ArgSpec] -> [ArgSpec]
forall a. a -> [a] -> [a]
: ArgInfo -> [ArgSpec]
ai_args ArgInfo
ai }
isStrictArgInfo :: ArgInfo -> Bool
isStrictArgInfo :: ArgInfo -> Bool
isStrictArgInfo (ArgInfo { ai_dmds :: ArgInfo -> [Demand]
ai_dmds = [Demand]
dmds })
| Demand
dmd:[Demand]
_ <- [Demand]
dmds = Demand -> Bool
isStrUsedDmd Demand
dmd
| Bool
otherwise = Bool
False
argInfoAppArgs :: [ArgSpec] -> [OutExpr]
argInfoAppArgs :: [ArgSpec] -> [Expr Id]
argInfoAppArgs [] = []
argInfoAppArgs (CastBy {} : [ArgSpec]
_) = []
argInfoAppArgs (ValArg { as_arg :: ArgSpec -> Expr Id
as_arg = Expr Id
arg } : [ArgSpec]
as) = Expr Id
arg Expr Id -> [Expr Id] -> [Expr Id]
forall a. a -> [a] -> [a]
: [ArgSpec] -> [Expr Id]
argInfoAppArgs [ArgSpec]
as
argInfoAppArgs (TyArg { as_arg_ty :: ArgSpec -> OutType
as_arg_ty = OutType
ty } : [ArgSpec]
as) = OutType -> Expr Id
forall b. OutType -> Expr b
Type OutType
ty Expr Id -> [Expr Id] -> [Expr Id]
forall a. a -> [a] -> [a]
: [ArgSpec] -> [Expr Id]
argInfoAppArgs [ArgSpec]
as
pushSimplifiedArgs :: SimplEnv -> [ArgSpec] -> SimplCont -> SimplCont
pushSimplifiedArgs :: StaticEnv -> [ArgSpec] -> SimplCont -> SimplCont
pushSimplifiedArgs StaticEnv
_env [] SimplCont
k = SimplCont
k
pushSimplifiedArgs StaticEnv
env (ArgSpec
arg : [ArgSpec]
args) SimplCont
k
= case ArgSpec
arg of
TyArg { as_arg_ty :: ArgSpec -> OutType
as_arg_ty = OutType
arg_ty, as_hole_ty :: ArgSpec -> OutType
as_hole_ty = OutType
hole_ty }
-> ApplyToTy { sc_arg_ty :: OutType
sc_arg_ty = OutType
arg_ty, sc_hole_ty :: OutType
sc_hole_ty = OutType
hole_ty, sc_cont :: SimplCont
sc_cont = SimplCont
rest }
ValArg { as_arg :: ArgSpec -> Expr Id
as_arg = Expr Id
arg, as_hole_ty :: ArgSpec -> OutType
as_hole_ty = OutType
hole_ty }
-> ApplyToVal { sc_arg :: Expr Id
sc_arg = Expr Id
arg, sc_env :: StaticEnv
sc_env = StaticEnv
env, sc_dup :: DupFlag
sc_dup = DupFlag
Simplified
, sc_hole_ty :: OutType
sc_hole_ty = OutType
hole_ty, sc_cont :: SimplCont
sc_cont = SimplCont
rest }
CastBy OutCoercion
c -> OutCoercion -> SimplCont -> SimplCont
CastIt OutCoercion
c SimplCont
rest
where
rest :: SimplCont
rest = StaticEnv -> [ArgSpec] -> SimplCont -> SimplCont
pushSimplifiedArgs StaticEnv
env [ArgSpec]
args SimplCont
k
argInfoExpr :: OutId -> [ArgSpec] -> OutExpr
argInfoExpr :: Id -> [ArgSpec] -> Expr Id
argInfoExpr Id
fun [ArgSpec]
rev_args
= [ArgSpec] -> Expr Id
go [ArgSpec]
rev_args
where
go :: [ArgSpec] -> Expr Id
go [] = Id -> Expr Id
forall b. Id -> Expr b
Var Id
fun
go (ValArg { as_arg :: ArgSpec -> Expr Id
as_arg = Expr Id
arg } : [ArgSpec]
as) = [ArgSpec] -> Expr Id
go [ArgSpec]
as Expr Id -> Expr Id -> Expr Id
forall b. Expr b -> Expr b -> Expr b
`App` Expr Id
arg
go (TyArg { as_arg_ty :: ArgSpec -> OutType
as_arg_ty = OutType
ty } : [ArgSpec]
as) = [ArgSpec] -> Expr Id
go [ArgSpec]
as Expr Id -> Expr Id -> Expr Id
forall b. Expr b -> Expr b -> Expr b
`App` OutType -> Expr Id
forall b. OutType -> Expr b
Type OutType
ty
go (CastBy OutCoercion
co : [ArgSpec]
as) = Expr Id -> OutCoercion -> Expr Id
mkCast ([ArgSpec] -> Expr Id
go [ArgSpec]
as) OutCoercion
co
type FunRules = Maybe (Int, [CoreRule])
decRules :: FunRules -> FunRules
decRules :: FunRules -> FunRules
decRules (Just (Arity
n, [CoreRule]
rules)) = (Arity, [CoreRule]) -> FunRules
forall a. a -> Maybe a
Just (Arity
nArity -> Arity -> Arity
forall a. Num a => a -> a -> a
-Arity
1, [CoreRule]
rules)
decRules FunRules
Nothing = FunRules
forall a. Maybe a
Nothing
mkFunRules :: [CoreRule] -> FunRules
mkFunRules :: [CoreRule] -> FunRules
mkFunRules [] = FunRules
forall a. Maybe a
Nothing
mkFunRules [CoreRule]
rs = (Arity, [CoreRule]) -> FunRules
forall a. a -> Maybe a
Just (Arity
n_required, [CoreRule]
rs)
where
n_required :: Arity
n_required = [Arity] -> Arity
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ((CoreRule -> Arity) -> [CoreRule] -> [Arity]
forall a b. (a -> b) -> [a] -> [b]
map CoreRule -> Arity
ruleArity [CoreRule]
rs)
mkBoringStop :: OutType -> SimplCont
mkBoringStop :: OutType -> SimplCont
mkBoringStop OutType
ty = OutType -> CallCtxt -> SimplCont
Stop OutType
ty CallCtxt
BoringCtxt
mkRhsStop :: OutType -> SimplCont
mkRhsStop :: OutType -> SimplCont
mkRhsStop OutType
ty = OutType -> CallCtxt -> SimplCont
Stop OutType
ty CallCtxt
RhsCtxt
mkLazyArgStop :: OutType -> CallCtxt -> SimplCont
mkLazyArgStop :: OutType -> CallCtxt -> SimplCont
mkLazyArgStop OutType
ty CallCtxt
cci = OutType -> CallCtxt -> SimplCont
Stop OutType
ty CallCtxt
cci
contIsRhsOrArg :: SimplCont -> Bool
contIsRhsOrArg :: SimplCont -> Bool
contIsRhsOrArg (Stop {}) = Bool
True
contIsRhsOrArg (StrictBind {}) = Bool
True
contIsRhsOrArg (StrictArg {}) = Bool
True
contIsRhsOrArg SimplCont
_ = Bool
False
contIsRhs :: SimplCont -> Bool
contIsRhs :: SimplCont -> Bool
contIsRhs (Stop OutType
_ CallCtxt
RhsCtxt) = Bool
True
contIsRhs (CastIt OutCoercion
_ SimplCont
k) = SimplCont -> Bool
contIsRhs SimplCont
k
contIsRhs SimplCont
_ = Bool
False
contIsStop :: SimplCont -> Bool
contIsStop :: SimplCont -> Bool
contIsStop (Stop {}) = Bool
True
contIsStop SimplCont
_ = Bool
False
contIsDupable :: SimplCont -> Bool
contIsDupable :: SimplCont -> Bool
contIsDupable (Stop {}) = Bool
True
contIsDupable (ApplyToTy { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = SimplCont -> Bool
contIsDupable SimplCont
k
contIsDupable (ApplyToVal { sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
OkToDup }) = Bool
True
contIsDupable (Select { sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
OkToDup }) = Bool
True
contIsDupable (StrictArg { sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
OkToDup }) = Bool
True
contIsDupable (CastIt OutCoercion
_ SimplCont
k) = SimplCont -> Bool
contIsDupable SimplCont
k
contIsDupable SimplCont
_ = Bool
False
contIsTrivial :: SimplCont -> Bool
contIsTrivial :: SimplCont -> Bool
contIsTrivial (Stop {}) = Bool
True
contIsTrivial (ApplyToTy { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = SimplCont -> Bool
contIsTrivial SimplCont
k
contIsTrivial (CastIt OutCoercion
_ SimplCont
k) = SimplCont -> Bool
contIsTrivial SimplCont
k
contIsTrivial SimplCont
_ = Bool
False
contResultType :: SimplCont -> OutType
contResultType :: SimplCont -> OutType
contResultType (Stop OutType
ty CallCtxt
_) = OutType
ty
contResultType (CastIt OutCoercion
_ SimplCont
k) = SimplCont -> OutType
contResultType SimplCont
k
contResultType (StrictBind { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = SimplCont -> OutType
contResultType SimplCont
k
contResultType (StrictArg { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = SimplCont -> OutType
contResultType SimplCont
k
contResultType (Select { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = SimplCont -> OutType
contResultType SimplCont
k
contResultType (ApplyToTy { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = SimplCont -> OutType
contResultType SimplCont
k
contResultType (ApplyToVal { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = SimplCont -> OutType
contResultType SimplCont
k
contResultType (TickIt CoreTickish
_ SimplCont
k) = SimplCont -> OutType
contResultType SimplCont
k
contHoleType :: SimplCont -> OutType
contHoleType :: SimplCont -> OutType
contHoleType (Stop OutType
ty CallCtxt
_) = OutType
ty
contHoleType (TickIt CoreTickish
_ SimplCont
k) = SimplCont -> OutType
contHoleType SimplCont
k
contHoleType (CastIt OutCoercion
co SimplCont
_) = OutCoercion -> OutType
coercionLKind OutCoercion
co
contHoleType (StrictBind { sc_bndr :: SimplCont -> Id
sc_bndr = Id
b, sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
dup, sc_env :: SimplCont -> StaticEnv
sc_env = StaticEnv
se })
= DupFlag -> StaticEnv -> OutType -> OutType
perhapsSubstTy DupFlag
dup StaticEnv
se (Id -> OutType
idType Id
b)
contHoleType (StrictArg { sc_fun_ty :: SimplCont -> OutType
sc_fun_ty = OutType
ty }) = OutType -> OutType
funArgTy OutType
ty
contHoleType (ApplyToTy { sc_hole_ty :: SimplCont -> OutType
sc_hole_ty = OutType
ty }) = OutType
ty
contHoleType (ApplyToVal { sc_hole_ty :: SimplCont -> OutType
sc_hole_ty = OutType
ty }) = OutType
ty
contHoleType (Select { sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
d, sc_bndr :: SimplCont -> Id
sc_bndr = Id
b, sc_env :: SimplCont -> StaticEnv
sc_env = StaticEnv
se })
= DupFlag -> StaticEnv -> OutType -> OutType
perhapsSubstTy DupFlag
d StaticEnv
se (Id -> OutType
idType Id
b)
contHoleScaling :: SimplCont -> Mult
contHoleScaling :: SimplCont -> OutType
contHoleScaling (Stop OutType
_ CallCtxt
_) = OutType
One
contHoleScaling (CastIt OutCoercion
_ SimplCont
k) = SimplCont -> OutType
contHoleScaling SimplCont
k
contHoleScaling (StrictBind { sc_bndr :: SimplCont -> Id
sc_bndr = Id
id, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k })
= Id -> OutType
idMult Id
id OutType -> OutType -> OutType
`mkMultMul` SimplCont -> OutType
contHoleScaling SimplCont
k
contHoleScaling (Select { sc_bndr :: SimplCont -> Id
sc_bndr = Id
id, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k })
= Id -> OutType
idMult Id
id OutType -> OutType -> OutType
`mkMultMul` SimplCont -> OutType
contHoleScaling SimplCont
k
contHoleScaling (StrictArg { sc_fun_ty :: SimplCont -> OutType
sc_fun_ty = OutType
fun_ty, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k })
= OutType
w OutType -> OutType -> OutType
`mkMultMul` SimplCont -> OutType
contHoleScaling SimplCont
k
where
(OutType
w, OutType
_, OutType
_) = OutType -> (OutType, OutType, OutType)
splitFunTy OutType
fun_ty
contHoleScaling (ApplyToTy { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = SimplCont -> OutType
contHoleScaling SimplCont
k
contHoleScaling (ApplyToVal { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = SimplCont -> OutType
contHoleScaling SimplCont
k
contHoleScaling (TickIt CoreTickish
_ SimplCont
k) = SimplCont -> OutType
contHoleScaling SimplCont
k
countArgs :: SimplCont -> Int
countArgs :: SimplCont -> Arity
countArgs (ApplyToTy { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont }) = Arity
1 Arity -> Arity -> Arity
forall a. Num a => a -> a -> a
+ SimplCont -> Arity
countArgs SimplCont
cont
countArgs (ApplyToVal { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont }) = Arity
1 Arity -> Arity -> Arity
forall a. Num a => a -> a -> a
+ SimplCont -> Arity
countArgs SimplCont
cont
countArgs (CastIt OutCoercion
_ SimplCont
cont) = SimplCont -> Arity
countArgs SimplCont
cont
countArgs SimplCont
_ = Arity
0
contArgs :: SimplCont -> (Bool, [ArgSummary], SimplCont)
contArgs :: SimplCont -> (Bool, [ArgSummary], SimplCont)
contArgs SimplCont
cont
| SimplCont -> Bool
lone SimplCont
cont = (Bool
True, [], SimplCont
cont)
| Bool
otherwise = [ArgSummary] -> SimplCont -> (Bool, [ArgSummary], SimplCont)
go [] SimplCont
cont
where
lone :: SimplCont -> Bool
lone (ApplyToTy {}) = Bool
False
lone (ApplyToVal {}) = Bool
False
lone (CastIt {}) = Bool
False
lone SimplCont
_ = Bool
True
go :: [ArgSummary] -> SimplCont -> (Bool, [ArgSummary], SimplCont)
go [ArgSummary]
args (ApplyToVal { sc_arg :: SimplCont -> Expr Id
sc_arg = Expr Id
arg, sc_env :: SimplCont -> StaticEnv
sc_env = StaticEnv
se, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k })
= [ArgSummary] -> SimplCont -> (Bool, [ArgSummary], SimplCont)
go (Expr Id -> StaticEnv -> ArgSummary
is_interesting Expr Id
arg StaticEnv
se ArgSummary -> [ArgSummary] -> [ArgSummary]
forall a. a -> [a] -> [a]
: [ArgSummary]
args) SimplCont
k
go [ArgSummary]
args (ApplyToTy { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = [ArgSummary] -> SimplCont -> (Bool, [ArgSummary], SimplCont)
go [ArgSummary]
args SimplCont
k
go [ArgSummary]
args (CastIt OutCoercion
_ SimplCont
k) = [ArgSummary] -> SimplCont -> (Bool, [ArgSummary], SimplCont)
go [ArgSummary]
args SimplCont
k
go [ArgSummary]
args SimplCont
k = (Bool
False, [ArgSummary] -> [ArgSummary]
forall a. [a] -> [a]
reverse [ArgSummary]
args, SimplCont
k)
is_interesting :: Expr Id -> StaticEnv -> ArgSummary
is_interesting Expr Id
arg StaticEnv
se = StaticEnv -> Expr Id -> ArgSummary
interestingArg StaticEnv
se Expr Id
arg
mkArgInfo :: SimplEnv
-> Id
-> [CoreRule]
-> Int
-> SimplCont
-> ArgInfo
mkArgInfo :: StaticEnv -> Id -> [CoreRule] -> Arity -> SimplCont -> ArgInfo
mkArgInfo StaticEnv
env Id
fun [CoreRule]
rules Arity
n_val_args SimplCont
call_cont
| Arity
n_val_args Arity -> Arity -> Bool
forall a. Ord a => a -> a -> Bool
< Id -> Arity
idArity Id
fun
= ArgInfo { ai_fun :: Id
ai_fun = Id
fun, ai_args :: [ArgSpec]
ai_args = []
, ai_rules :: FunRules
ai_rules = FunRules
fun_rules
, ai_encl :: Bool
ai_encl = Bool
False
, ai_dmds :: [Demand]
ai_dmds = [Demand]
vanilla_dmds
, ai_discs :: [Arity]
ai_discs = [Arity]
vanilla_discounts }
| Bool
otherwise
= ArgInfo { ai_fun :: Id
ai_fun = Id
fun
, ai_args :: [ArgSpec]
ai_args = []
, ai_rules :: FunRules
ai_rules = FunRules
fun_rules
, ai_encl :: Bool
ai_encl = [CoreRule] -> SimplCont -> Bool
interestingArgContext [CoreRule]
rules SimplCont
call_cont
, ai_dmds :: [Demand]
ai_dmds = OutType -> [Demand] -> [Demand]
add_type_strictness (Id -> OutType
idType Id
fun) [Demand]
arg_dmds
, ai_discs :: [Arity]
ai_discs = [Arity]
arg_discounts }
where
fun_rules :: FunRules
fun_rules = [CoreRule] -> FunRules
mkFunRules [CoreRule]
rules
vanilla_discounts, arg_discounts :: [Int]
vanilla_discounts :: [Arity]
vanilla_discounts = Arity -> [Arity]
forall a. a -> [a]
repeat Arity
0
arg_discounts :: [Arity]
arg_discounts = case Id -> Unfolding
idUnfolding Id
fun of
CoreUnfolding {uf_guidance :: Unfolding -> UnfoldingGuidance
uf_guidance = UnfIfGoodArgs {ug_args :: UnfoldingGuidance -> [Arity]
ug_args = [Arity]
discounts}}
-> [Arity]
discounts [Arity] -> [Arity] -> [Arity]
forall a. [a] -> [a] -> [a]
++ [Arity]
vanilla_discounts
Unfolding
_ -> [Arity]
vanilla_discounts
vanilla_dmds, arg_dmds :: [Demand]
vanilla_dmds :: [Demand]
vanilla_dmds = Demand -> [Demand]
forall a. a -> [a]
repeat Demand
topDmd
arg_dmds :: [Demand]
arg_dmds
| Bool -> Bool
not (SimplMode -> Bool
sm_inline (StaticEnv -> SimplMode
seMode StaticEnv
env))
= [Demand]
vanilla_dmds
| Bool
otherwise
=
case DmdSig -> ([Demand], Divergence)
splitDmdSig (Id -> DmdSig
idDmdSig Id
fun) of
([Demand]
demands, Divergence
result_info)
| Bool -> Bool
not ([Demand]
demands [Demand] -> Arity -> Bool
forall a. [a] -> Arity -> Bool
`lengthExceeds` Arity
n_val_args)
->
if Divergence -> Bool
isDeadEndDiv Divergence
result_info then
[Demand]
demands
else
[Demand]
demands [Demand] -> [Demand] -> [Demand]
forall a. [a] -> [a] -> [a]
++ [Demand]
vanilla_dmds
| Bool
otherwise
-> Bool -> String -> SDoc -> [Demand] -> [Demand]
forall a. HasCallStack => Bool -> String -> SDoc -> a -> a
warnPprTrace Bool
True String
"More demands than arity" (Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
fun SDoc -> SDoc -> SDoc
<+> Arity -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Id -> Arity
idArity Id
fun)
SDoc -> SDoc -> SDoc
<+> Arity -> SDoc
forall a. Outputable a => a -> SDoc
ppr Arity
n_val_args SDoc -> SDoc -> SDoc
<+> [Demand] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Demand]
demands) ([Demand] -> [Demand]) -> [Demand] -> [Demand]
forall a b. (a -> b) -> a -> b
$
[Demand]
vanilla_dmds
add_type_strictness :: Type -> [Demand] -> [Demand]
add_type_strictness :: OutType -> [Demand] -> [Demand]
add_type_strictness OutType
fun_ty [Demand]
dmds
| [Demand] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Demand]
dmds = []
| Just (Id
_, OutType
fun_ty') <- OutType -> Maybe (Id, OutType)
splitForAllTyCoVar_maybe OutType
fun_ty
= OutType -> [Demand] -> [Demand]
add_type_strictness OutType
fun_ty' [Demand]
dmds
| Just (OutType
_, OutType
arg_ty, OutType
fun_ty') <- OutType -> Maybe (OutType, OutType, OutType)
splitFunTy_maybe OutType
fun_ty
, Demand
dmd : [Demand]
rest_dmds <- [Demand]
dmds
, let dmd' :: Demand
dmd'
| Just Levity
Unlifted <- (() :: Constraint) => OutType -> Maybe Levity
OutType -> Maybe Levity
typeLevity_maybe OutType
arg_ty
= Demand -> Demand
strictifyDmd Demand
dmd
| Bool
otherwise
= Demand
dmd
= Demand
dmd' Demand -> [Demand] -> [Demand]
forall a. a -> [a] -> [a]
: OutType -> [Demand] -> [Demand]
add_type_strictness OutType
fun_ty' [Demand]
rest_dmds
| Bool
otherwise
= [Demand]
dmds
lazyArgContext :: ArgInfo -> CallCtxt
lazyArgContext :: ArgInfo -> CallCtxt
lazyArgContext (ArgInfo { ai_encl :: ArgInfo -> Bool
ai_encl = Bool
encl_rules, ai_discs :: ArgInfo -> [Arity]
ai_discs = [Arity]
discs })
| Bool
encl_rules = CallCtxt
RuleArgCtxt
| Arity
disc:[Arity]
_ <- [Arity]
discs, Arity
disc Arity -> Arity -> Bool
forall a. Ord a => a -> a -> Bool
> Arity
0 = CallCtxt
DiscArgCtxt
| Bool
otherwise = CallCtxt
BoringCtxt
strictArgContext :: ArgInfo -> CallCtxt
strictArgContext :: ArgInfo -> CallCtxt
strictArgContext (ArgInfo { ai_encl :: ArgInfo -> Bool
ai_encl = Bool
encl_rules, ai_discs :: ArgInfo -> [Arity]
ai_discs = [Arity]
discs })
| Bool
encl_rules = CallCtxt
RuleArgCtxt
| Arity
disc:[Arity]
_ <- [Arity]
discs, Arity
disc Arity -> Arity -> Bool
forall a. Ord a => a -> a -> Bool
> Arity
0 = CallCtxt
DiscArgCtxt
| Bool
otherwise = CallCtxt
RhsCtxt
interestingCallContext :: SimplEnv -> SimplCont -> CallCtxt
interestingCallContext :: StaticEnv -> SimplCont -> CallCtxt
interestingCallContext StaticEnv
env SimplCont
cont
= SimplCont -> CallCtxt
interesting SimplCont
cont
where
interesting :: SimplCont -> CallCtxt
interesting (Select {})
| SimplMode -> Bool
sm_case_case (StaticEnv -> SimplMode
getMode StaticEnv
env) = CallCtxt
CaseCtxt
| Bool
otherwise = CallCtxt
BoringCtxt
interesting (ApplyToVal {}) = CallCtxt
ValAppCtxt
interesting (StrictArg { sc_fun :: SimplCont -> ArgInfo
sc_fun = ArgInfo
fun }) = ArgInfo -> CallCtxt
strictArgContext ArgInfo
fun
interesting (StrictBind {}) = CallCtxt
BoringCtxt
interesting (Stop OutType
_ CallCtxt
cci) = CallCtxt
cci
interesting (TickIt CoreTickish
_ SimplCont
k) = SimplCont -> CallCtxt
interesting SimplCont
k
interesting (ApplyToTy { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = SimplCont -> CallCtxt
interesting SimplCont
k
interesting (CastIt OutCoercion
_ SimplCont
k) = SimplCont -> CallCtxt
interesting SimplCont
k
interestingArgContext :: [CoreRule] -> SimplCont -> Bool
interestingArgContext :: [CoreRule] -> SimplCont -> Bool
interestingArgContext [CoreRule]
rules SimplCont
call_cont
= [CoreRule] -> Bool
forall (f :: * -> *) a. Foldable f => f a -> Bool
notNull [CoreRule]
rules Bool -> Bool -> Bool
|| Bool
enclosing_fn_has_rules
where
enclosing_fn_has_rules :: Bool
enclosing_fn_has_rules = SimplCont -> Bool
go SimplCont
call_cont
go :: SimplCont -> Bool
go (Select {}) = Bool
False
go (ApplyToVal {}) = Bool
False
go (ApplyToTy {}) = Bool
False
go (StrictArg { sc_fun :: SimplCont -> ArgInfo
sc_fun = ArgInfo
fun }) = ArgInfo -> Bool
ai_encl ArgInfo
fun
go (StrictBind {}) = Bool
False
go (CastIt OutCoercion
_ SimplCont
c) = SimplCont -> Bool
go SimplCont
c
go (Stop OutType
_ CallCtxt
RuleArgCtxt) = Bool
True
go (Stop OutType
_ CallCtxt
_) = Bool
False
go (TickIt CoreTickish
_ SimplCont
c) = SimplCont -> Bool
go SimplCont
c
interestingArg :: SimplEnv -> CoreExpr -> ArgSummary
interestingArg :: StaticEnv -> Expr Id -> ArgSummary
interestingArg StaticEnv
env Expr Id
e = StaticEnv -> Arity -> Expr Id -> ArgSummary
go StaticEnv
env Arity
0 Expr Id
e
where
go :: StaticEnv -> Arity -> Expr Id -> ArgSummary
go StaticEnv
env Arity
n (Var Id
v)
= case StaticEnv -> Id -> SimplSR
substId StaticEnv
env Id
v of
DoneId Id
v' -> Arity -> Id -> ArgSummary
go_var Arity
n Id
v'
DoneEx Expr Id
e Maybe Arity
_ -> StaticEnv -> Arity -> Expr Id -> ArgSummary
go (StaticEnv -> StaticEnv
zapSubstEnv StaticEnv
env) Arity
n Expr Id
e
ContEx TvSubstEnv
tvs CvSubstEnv
cvs SimplIdSubst
ids Expr Id
e -> StaticEnv -> Arity -> Expr Id -> ArgSummary
go (StaticEnv -> TvSubstEnv -> CvSubstEnv -> SimplIdSubst -> StaticEnv
setSubstEnv StaticEnv
env TvSubstEnv
tvs CvSubstEnv
cvs SimplIdSubst
ids) Arity
n Expr Id
e
go StaticEnv
_ Arity
_ (Lit Literal
l)
| Literal -> Bool
isLitRubbish Literal
l = ArgSummary
TrivArg
| Bool
otherwise = ArgSummary
ValueArg
go StaticEnv
_ Arity
_ (Type OutType
_) = ArgSummary
TrivArg
go StaticEnv
_ Arity
_ (Coercion OutCoercion
_) = ArgSummary
TrivArg
go StaticEnv
env Arity
n (App Expr Id
fn (Type OutType
_)) = StaticEnv -> Arity -> Expr Id -> ArgSummary
go StaticEnv
env Arity
n Expr Id
fn
go StaticEnv
env Arity
n (App Expr Id
fn Expr Id
_) = StaticEnv -> Arity -> Expr Id -> ArgSummary
go StaticEnv
env (Arity
nArity -> Arity -> Arity
forall a. Num a => a -> a -> a
+Arity
1) Expr Id
fn
go StaticEnv
env Arity
n (Tick CoreTickish
_ Expr Id
a) = StaticEnv -> Arity -> Expr Id -> ArgSummary
go StaticEnv
env Arity
n Expr Id
a
go StaticEnv
env Arity
n (Cast Expr Id
e OutCoercion
_) = StaticEnv -> Arity -> Expr Id -> ArgSummary
go StaticEnv
env Arity
n Expr Id
e
go StaticEnv
env Arity
n (Lam Id
v Expr Id
e)
| Id -> Bool
isTyVar Id
v = StaticEnv -> Arity -> Expr Id -> ArgSummary
go StaticEnv
env Arity
n Expr Id
e
| Arity
nArity -> Arity -> Bool
forall a. Ord a => a -> a -> Bool
>Arity
0 = ArgSummary
NonTrivArg
| Bool
otherwise = ArgSummary
ValueArg
go StaticEnv
_ Arity
_ (Case {}) = ArgSummary
NonTrivArg
go StaticEnv
env Arity
n (Let Bind Id
b Expr Id
e) = case StaticEnv -> Arity -> Expr Id -> ArgSummary
go StaticEnv
env' Arity
n Expr Id
e of
ArgSummary
ValueArg -> ArgSummary
ValueArg
ArgSummary
_ -> ArgSummary
NonTrivArg
where
env' :: StaticEnv
env' = StaticEnv
env StaticEnv -> [Id] -> StaticEnv
`addNewInScopeIds` Bind Id -> [Id]
forall b. Bind b -> [b]
bindersOf Bind Id
b
go_var :: Arity -> Id -> ArgSummary
go_var Arity
n Id
v
| Id -> Bool
isConLikeId Id
v = ArgSummary
ValueArg
| Id -> Arity
idArity Id
v Arity -> Arity -> Bool
forall a. Ord a => a -> a -> Bool
> Arity
n = ArgSummary
ValueArg
| Arity
n Arity -> Arity -> Bool
forall a. Ord a => a -> a -> Bool
> Arity
0 = ArgSummary
NonTrivArg
| Bool
conlike_unfolding = ArgSummary
ValueArg
| Bool
otherwise = ArgSummary
TrivArg
where
conlike_unfolding :: Bool
conlike_unfolding = Unfolding -> Bool
isConLikeUnfolding (Id -> Unfolding
idUnfolding Id
v)
simplEnvForGHCi :: Logger -> DynFlags -> SimplEnv
simplEnvForGHCi :: Logger -> DynFlags -> StaticEnv
simplEnvForGHCi Logger
logger DynFlags
dflags
= SimplMode -> StaticEnv
mkSimplEnv (SimplMode -> StaticEnv) -> SimplMode -> StaticEnv
forall a b. (a -> b) -> a -> b
$ SimplMode { sm_names :: [String]
sm_names = [String
"GHCi"]
, sm_phase :: CompilerPhase
sm_phase = CompilerPhase
InitialPhase
, sm_logger :: Logger
sm_logger = Logger
logger
, sm_dflags :: DynFlags
sm_dflags = DynFlags
dflags
, sm_uf_opts :: UnfoldingOpts
sm_uf_opts = UnfoldingOpts
uf_opts
, sm_rules :: Bool
sm_rules = Bool
rules_on
, sm_inline :: Bool
sm_inline = Bool
False
, sm_eta_expand :: Bool
sm_eta_expand = Bool
eta_expand_on
, sm_cast_swizzle :: Bool
sm_cast_swizzle = Bool
True
, sm_case_case :: Bool
sm_case_case = Bool
True
, sm_pre_inline :: Bool
sm_pre_inline = Bool
pre_inline_on
}
where
rules_on :: Bool
rules_on = GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_EnableRewriteRules DynFlags
dflags
eta_expand_on :: Bool
eta_expand_on = GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_DoLambdaEtaExpansion DynFlags
dflags
pre_inline_on :: Bool
pre_inline_on = GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_SimplPreInlining DynFlags
dflags
uf_opts :: UnfoldingOpts
uf_opts = DynFlags -> UnfoldingOpts
unfoldingOpts DynFlags
dflags
updModeForStableUnfoldings :: Activation -> SimplMode -> SimplMode
updModeForStableUnfoldings :: Activation -> SimplMode -> SimplMode
updModeForStableUnfoldings Activation
unf_act SimplMode
current_mode
= SimplMode
current_mode { sm_phase :: CompilerPhase
sm_phase = Activation -> CompilerPhase
phaseFromActivation Activation
unf_act
, sm_eta_expand :: Bool
sm_eta_expand = Bool
False
, sm_inline :: Bool
sm_inline = Bool
True }
where
phaseFromActivation :: Activation -> CompilerPhase
phaseFromActivation (ActiveAfter SourceText
_ Arity
n) = Arity -> CompilerPhase
Phase Arity
n
phaseFromActivation Activation
_ = CompilerPhase
InitialPhase
updModeForRules :: SimplMode -> SimplMode
updModeForRules :: SimplMode -> SimplMode
updModeForRules SimplMode
current_mode
= SimplMode
current_mode { sm_phase :: CompilerPhase
sm_phase = CompilerPhase
InitialPhase
, sm_inline :: Bool
sm_inline = Bool
False
, sm_rules :: Bool
sm_rules = Bool
False
, sm_cast_swizzle :: Bool
sm_cast_swizzle = Bool
False
, sm_eta_expand :: Bool
sm_eta_expand = Bool
False }
activeUnfolding :: SimplMode -> Id -> Bool
activeUnfolding :: SimplMode -> Id -> Bool
activeUnfolding SimplMode
mode Id
id
| Unfolding -> Bool
isCompulsoryUnfolding (Id -> Unfolding
realIdUnfolding Id
id)
= Bool
True
| Bool
otherwise
= CompilerPhase -> Activation -> Bool
isActive (SimplMode -> CompilerPhase
sm_phase SimplMode
mode) (Id -> Activation
idInlineActivation Id
id)
Bool -> Bool -> Bool
&& SimplMode -> Bool
sm_inline SimplMode
mode
getUnfoldingInRuleMatch :: SimplEnv -> InScopeEnv
getUnfoldingInRuleMatch :: StaticEnv -> InScopeEnv
getUnfoldingInRuleMatch StaticEnv
env
= (InScopeSet
in_scope, Id -> Unfolding
id_unf)
where
in_scope :: InScopeSet
in_scope = StaticEnv -> InScopeSet
seInScope StaticEnv
env
mode :: SimplMode
mode = StaticEnv -> SimplMode
getMode StaticEnv
env
id_unf :: Id -> Unfolding
id_unf Id
id | Id -> Bool
unf_is_active Id
id = Id -> Unfolding
idUnfolding Id
id
| Bool
otherwise = Unfolding
NoUnfolding
unf_is_active :: Id -> Bool
unf_is_active Id
id = CompilerPhase -> Activation -> Bool
isActive (SimplMode -> CompilerPhase
sm_phase SimplMode
mode) (Id -> Activation
idInlineActivation Id
id)
activeRule :: SimplMode -> Activation -> Bool
activeRule :: SimplMode -> Activation -> Bool
activeRule SimplMode
mode
| Bool -> Bool
not (SimplMode -> Bool
sm_rules SimplMode
mode) = \Activation
_ -> Bool
False
| Bool
otherwise = CompilerPhase -> Activation -> Bool
isActive (SimplMode -> CompilerPhase
sm_phase SimplMode
mode)
preInlineUnconditionally
:: SimplEnv -> TopLevelFlag -> InId
-> InExpr -> StaticEnv
-> Maybe SimplEnv
preInlineUnconditionally :: StaticEnv
-> TopLevelFlag -> Id -> Expr Id -> StaticEnv -> Maybe StaticEnv
preInlineUnconditionally StaticEnv
env TopLevelFlag
top_lvl Id
bndr Expr Id
rhs StaticEnv
rhs_env
| Bool -> Bool
not Bool
pre_inline_unconditionally = Maybe StaticEnv
forall a. Maybe a
Nothing
| Bool -> Bool
not Bool
active = Maybe StaticEnv
forall a. Maybe a
Nothing
| TopLevelFlag -> Bool
isTopLevel TopLevelFlag
top_lvl Bool -> Bool -> Bool
&& Id -> Bool
isDeadEndId Id
bndr = Maybe StaticEnv
forall a. Maybe a
Nothing
| Id -> Bool
isCoVar Id
bndr = Maybe StaticEnv
forall a. Maybe a
Nothing
| Id -> Bool
isExitJoinId Id
bndr = Maybe StaticEnv
forall a. Maybe a
Nothing
| Bool -> Bool
not (OccInfo -> Bool
one_occ (Id -> OccInfo
idOccInfo Id
bndr)) = Maybe StaticEnv
forall a. Maybe a
Nothing
| Bool -> Bool
not (Unfolding -> Bool
isStableUnfolding Unfolding
unf) = StaticEnv -> Maybe StaticEnv
forall a. a -> Maybe a
Just (StaticEnv -> Maybe StaticEnv) -> StaticEnv -> Maybe StaticEnv
forall a b. (a -> b) -> a -> b
$! (Expr Id -> StaticEnv
extend_subst_with Expr Id
rhs)
| Bool -> Bool
not (InlinePragma -> Bool
isInlinePragma InlinePragma
inline_prag)
, Just Expr Id
inl <- Unfolding -> Maybe (Expr Id)
maybeUnfoldingTemplate Unfolding
unf = StaticEnv -> Maybe StaticEnv
forall a. a -> Maybe a
Just (StaticEnv -> Maybe StaticEnv) -> StaticEnv -> Maybe StaticEnv
forall a b. (a -> b) -> a -> b
$! (Expr Id -> StaticEnv
extend_subst_with Expr Id
inl)
| Bool
otherwise = Maybe StaticEnv
forall a. Maybe a
Nothing
where
unf :: Unfolding
unf = Id -> Unfolding
idUnfolding Id
bndr
extend_subst_with :: Expr Id -> StaticEnv
extend_subst_with Expr Id
inl_rhs = StaticEnv -> Id -> SimplSR -> StaticEnv
extendIdSubst StaticEnv
env Id
bndr (SimplSR -> StaticEnv) -> SimplSR -> StaticEnv
forall a b. (a -> b) -> a -> b
$! (StaticEnv -> Expr Id -> SimplSR
mkContEx StaticEnv
rhs_env Expr Id
inl_rhs)
one_occ :: OccInfo -> Bool
one_occ OccInfo
IAmDead = Bool
True
one_occ OneOcc{ occ_n_br :: OccInfo -> Arity
occ_n_br = Arity
1
, occ_in_lam :: OccInfo -> InsideLam
occ_in_lam = InsideLam
NotInsideLam } = TopLevelFlag -> Bool
isNotTopLevel TopLevelFlag
top_lvl Bool -> Bool -> Bool
|| Bool
early_phase
one_occ OneOcc{ occ_n_br :: OccInfo -> Arity
occ_n_br = Arity
1
, occ_in_lam :: OccInfo -> InsideLam
occ_in_lam = InsideLam
IsInsideLam
, occ_int_cxt :: OccInfo -> InterestingCxt
occ_int_cxt = InterestingCxt
IsInteresting } = Expr Id -> Bool
canInlineInLam Expr Id
rhs
one_occ OccInfo
_ = Bool
False
pre_inline_unconditionally :: Bool
pre_inline_unconditionally = SimplMode -> Bool
sm_pre_inline SimplMode
mode
mode :: SimplMode
mode = StaticEnv -> SimplMode
getMode StaticEnv
env
active :: Bool
active = CompilerPhase -> Activation -> Bool
isActive (SimplMode -> CompilerPhase
sm_phase SimplMode
mode) (InlinePragma -> Activation
inlinePragmaActivation InlinePragma
inline_prag)
inline_prag :: InlinePragma
inline_prag = Id -> InlinePragma
idInlinePragma Id
bndr
canInlineInLam :: Expr Id -> Bool
canInlineInLam (Lit Literal
_) = Bool
True
canInlineInLam (Lam Id
b Expr Id
e) = Id -> Bool
isRuntimeVar Id
b Bool -> Bool -> Bool
|| Expr Id -> Bool
canInlineInLam Expr Id
e
canInlineInLam (Tick CoreTickish
t Expr Id
e) = Bool -> Bool
not (CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishIsCode CoreTickish
t) Bool -> Bool -> Bool
&& Expr Id -> Bool
canInlineInLam Expr Id
e
canInlineInLam Expr Id
_ = Bool
False
early_phase :: Bool
early_phase = SimplMode -> CompilerPhase
sm_phase SimplMode
mode CompilerPhase -> CompilerPhase -> Bool
forall a. Eq a => a -> a -> Bool
/= CompilerPhase
FinalPhase
postInlineUnconditionally
:: SimplEnv -> BindContext
-> OutId
-> OccInfo
-> OutExpr
-> Bool
postInlineUnconditionally :: StaticEnv -> BindContext -> Id -> OccInfo -> Expr Id -> Bool
postInlineUnconditionally StaticEnv
env BindContext
bind_cxt Id
bndr OccInfo
occ_info Expr Id
rhs
| Bool -> Bool
not Bool
active = Bool
False
| OccInfo -> Bool
isWeakLoopBreaker OccInfo
occ_info = Bool
False
| Unfolding -> Bool
isStableUnfolding Unfolding
unfolding = Bool
False
| TopLevelFlag -> Bool
isTopLevel (BindContext -> TopLevelFlag
bindContextLevel BindContext
bind_cxt)
= Bool
False
| Expr Id -> Bool
exprIsTrivial Expr Id
rhs = Bool
True
| BC_Join {} <- BindContext
bind_cxt
, Bool -> Bool
not (CompilerPhase
phase CompilerPhase -> CompilerPhase -> Bool
forall a. Eq a => a -> a -> Bool
== CompilerPhase
FinalPhase) = Bool
False
| Bool
otherwise
= case OccInfo
occ_info of
OneOcc { occ_in_lam :: OccInfo -> InsideLam
occ_in_lam = InsideLam
in_lam, occ_int_cxt :: OccInfo -> InterestingCxt
occ_int_cxt = InterestingCxt
int_cxt, occ_n_br :: OccInfo -> Arity
occ_n_br = Arity
n_br }
-> Arity
n_br Arity -> Arity -> Bool
forall a. Ord a => a -> a -> Bool
< Arity
100
Bool -> Bool -> Bool
&& UnfoldingOpts -> Unfolding -> Bool
smallEnoughToInline UnfoldingOpts
uf_opts Unfolding
unfolding
Bool -> Bool -> Bool
&& (InsideLam
in_lam InsideLam -> InsideLam -> Bool
forall a. Eq a => a -> a -> Bool
== InsideLam
NotInsideLam Bool -> Bool -> Bool
||
(Unfolding -> Bool
isCheapUnfolding Unfolding
unfolding Bool -> Bool -> Bool
&& InterestingCxt
int_cxt InterestingCxt -> InterestingCxt -> Bool
forall a. Eq a => a -> a -> Bool
== InterestingCxt
IsInteresting))
OccInfo
IAmDead -> Bool
True
OccInfo
_ -> Bool
False
where
unfolding :: Unfolding
unfolding = Id -> Unfolding
idUnfolding Id
bndr
uf_opts :: UnfoldingOpts
uf_opts = StaticEnv -> UnfoldingOpts
seUnfoldingOpts StaticEnv
env
phase :: CompilerPhase
phase = SimplMode -> CompilerPhase
sm_phase (StaticEnv -> SimplMode
getMode StaticEnv
env)
active :: Bool
active = CompilerPhase -> Activation -> Bool
isActive CompilerPhase
phase (Id -> Activation
idInlineActivation Id
bndr)
mkLam :: SimplEnv -> [OutBndr] -> OutExpr -> SimplCont -> SimplM OutExpr
mkLam :: StaticEnv -> [Id] -> Expr Id -> SimplCont -> SimplM (Expr Id)
mkLam StaticEnv
_env [] Expr Id
body SimplCont
_cont
= Expr Id -> SimplM (Expr Id)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return Expr Id
body
mkLam StaticEnv
env [Id]
bndrs Expr Id
body SimplCont
cont
= {-#SCC "mkLam" #-}
do { DynFlags
dflags <- SimplM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; DynFlags -> [Id] -> Expr Id -> SimplM (Expr Id)
mkLam' DynFlags
dflags [Id]
bndrs Expr Id
body }
where
mode :: SimplMode
mode = StaticEnv -> SimplMode
getMode StaticEnv
env
rec_ids :: UnVarSet
rec_ids = StaticEnv -> UnVarSet
seRecIds StaticEnv
env
mkLam' :: DynFlags -> [OutBndr] -> OutExpr -> SimplM OutExpr
mkLam' :: DynFlags -> [Id] -> Expr Id -> SimplM (Expr Id)
mkLam' DynFlags
dflags [Id]
bndrs body :: Expr Id
body@(Lam {})
= DynFlags -> [Id] -> Expr Id -> SimplM (Expr Id)
mkLam' DynFlags
dflags ([Id]
bndrs [Id] -> [Id] -> [Id]
forall a. [a] -> [a] -> [a]
++ [Id]
bndrs1) Expr Id
body1
where
([Id]
bndrs1, Expr Id
body1) = Expr Id -> ([Id], Expr Id)
forall b. Expr b -> ([b], Expr b)
collectBinders Expr Id
body
mkLam' DynFlags
dflags [Id]
bndrs (Tick CoreTickish
t Expr Id
expr)
| CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishFloatable CoreTickish
t
= CoreTickish -> Expr Id -> Expr Id
mkTick CoreTickish
t (Expr Id -> Expr Id) -> SimplM (Expr Id) -> SimplM (Expr Id)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DynFlags -> [Id] -> Expr Id -> SimplM (Expr Id)
mkLam' DynFlags
dflags [Id]
bndrs Expr Id
expr
mkLam' DynFlags
dflags [Id]
bndrs (Cast Expr Id
body OutCoercion
co)
|
SimplMode -> Bool
sm_cast_swizzle SimplMode
mode
, Bool -> Bool
not ((Id -> Bool) -> [Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Id -> Bool
bad [Id]
bndrs)
= do { Expr Id
lam <- DynFlags -> [Id] -> Expr Id -> SimplM (Expr Id)
mkLam' DynFlags
dflags [Id]
bndrs Expr Id
body
; Expr Id -> SimplM (Expr Id)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Expr Id -> OutCoercion -> Expr Id
mkCast Expr Id
lam (Role -> [Id] -> OutCoercion -> OutCoercion
mkPiCos Role
Representational [Id]
bndrs OutCoercion
co)) }
where
co_vars :: TyCoVarSet
co_vars = OutCoercion -> TyCoVarSet
tyCoVarsOfCo OutCoercion
co
bad :: Id -> Bool
bad Id
bndr = Id -> Bool
isCoVar Id
bndr Bool -> Bool -> Bool
&& Id
bndr Id -> TyCoVarSet -> Bool
`elemVarSet` TyCoVarSet
co_vars
mkLam' DynFlags
dflags [Id]
bndrs Expr Id
body
| GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_DoEtaReduction DynFlags
dflags
, Just Expr Id
etad_lam <- {-# SCC "tryee" #-} UnVarSet -> [Id] -> Expr Id -> Maybe (Expr Id)
tryEtaReduce UnVarSet
rec_ids [Id]
bndrs Expr Id
body
= do { Tick -> SimplM ()
tick (Id -> Tick
EtaReduction ([Id] -> Id
forall a. HasCallStack => [a] -> a
head [Id]
bndrs))
; Expr Id -> SimplM (Expr Id)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return Expr Id
etad_lam }
| Bool -> Bool
not (SimplCont -> Bool
contIsRhs SimplCont
cont)
, SimplMode -> Bool
sm_eta_expand SimplMode
mode
, (Id -> Bool) -> [Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Id -> Bool
isRuntimeVar [Id]
bndrs
, let body_arity :: ArityType
body_arity = {-# SCC "eta" #-} DynFlags -> Expr Id -> ArityType
exprEtaExpandArity DynFlags
dflags Expr Id
body
, ArityType -> Bool
expandableArityType ArityType
body_arity
= do { Tick -> SimplM ()
tick (Id -> Tick
EtaExpansion ([Id] -> Id
forall a. HasCallStack => [a] -> a
head [Id]
bndrs))
; let res :: Expr Id
res = {-# SCC "eta3" #-}
[Id] -> Expr Id -> Expr Id
forall b. [b] -> Expr b -> Expr b
mkLams [Id]
bndrs (Expr Id -> Expr Id) -> Expr Id -> Expr Id
forall a b. (a -> b) -> a -> b
$
InScopeSet -> ArityType -> Expr Id -> Expr Id
etaExpandAT InScopeSet
in_scope ArityType
body_arity Expr Id
body
; String -> SDoc -> SimplM ()
traceSmpl String
"eta expand" ([SDoc] -> SDoc
vcat [String -> SDoc
text String
"before" SDoc -> SDoc -> SDoc
<+> Expr Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr ([Id] -> Expr Id -> Expr Id
forall b. [b] -> Expr b -> Expr b
mkLams [Id]
bndrs Expr Id
body)
, String -> SDoc
text String
"after" SDoc -> SDoc -> SDoc
<+> Expr Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Expr Id
res])
; Expr Id -> SimplM (Expr Id)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return Expr Id
res }
| Bool
otherwise
= Expr Id -> SimplM (Expr Id)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Id] -> Expr Id -> Expr Id
forall b. [b] -> Expr b -> Expr b
mkLams [Id]
bndrs Expr Id
body)
where
in_scope :: InScopeSet
in_scope = StaticEnv -> InScopeSet
getInScope StaticEnv
env
tryEtaExpandRhs :: SimplEnv -> OutId -> OutExpr
-> SimplM (ArityType, OutExpr)
tryEtaExpandRhs :: StaticEnv -> Id -> Expr Id -> SimplM (ArityType, Expr Id)
tryEtaExpandRhs StaticEnv
env Id
bndr Expr Id
rhs
| Just Arity
join_arity <- Id -> Maybe Arity
isJoinId_maybe Id
bndr
= do { let ([Id]
join_bndrs, Expr Id
join_body) = Arity -> Expr Id -> ([Id], Expr Id)
forall b. Arity -> Expr b -> ([b], Expr b)
collectNBinders Arity
join_arity Expr Id
rhs
arity_type :: ArityType
arity_type = [Id] -> Expr Id -> ArityType
mkManifestArityType [Id]
join_bndrs Expr Id
join_body
; (ArityType, Expr Id) -> SimplM (ArityType, Expr Id)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return (ArityType
arity_type, Expr Id
rhs) }
| SimplMode -> Bool
sm_eta_expand SimplMode
mode
, Arity
new_arity Arity -> Arity -> Bool
forall a. Ord a => a -> a -> Bool
> Arity
old_arity
, Expr Id -> Bool
want_eta Expr Id
rhs
= do { Tick -> SimplM ()
tick (Id -> Tick
EtaExpansion Id
bndr)
; (ArityType, Expr Id) -> SimplM (ArityType, Expr Id)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return (ArityType
arity_type, InScopeSet -> ArityType -> Expr Id -> Expr Id
etaExpandAT InScopeSet
in_scope ArityType
arity_type Expr Id
rhs) }
| Bool
otherwise
= (ArityType, Expr Id) -> SimplM (ArityType, Expr Id)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return (ArityType
arity_type, Expr Id
rhs)
where
mode :: SimplMode
mode = StaticEnv -> SimplMode
getMode StaticEnv
env
in_scope :: InScopeSet
in_scope = StaticEnv -> InScopeSet
getInScope StaticEnv
env
dflags :: DynFlags
dflags = SimplMode -> DynFlags
sm_dflags SimplMode
mode
old_arity :: Arity
old_arity = Expr Id -> Arity
exprArity Expr Id
rhs
arity_type :: ArityType
arity_type = DynFlags -> Id -> Expr Id -> Arity -> ArityType
findRhsArity DynFlags
dflags Id
bndr Expr Id
rhs Arity
old_arity
ArityType -> Arity -> ArityType
`maxWithArity` Id -> Arity
idCallArity Id
bndr
new_arity :: Arity
new_arity = ArityType -> Arity
arityTypeArity ArityType
arity_type
want_eta :: Expr Id -> Bool
want_eta (Cast Expr Id
e OutCoercion
_) = Expr Id -> Bool
want_eta Expr Id
e
want_eta (Tick CoreTickish
_ Expr Id
e) = Expr Id -> Bool
want_eta Expr Id
e
want_eta (Lam Id
b Expr Id
e) | Id -> Bool
isTyVar Id
b = Expr Id -> Bool
want_eta Expr Id
e
want_eta (App Expr Id
e Expr Id
a) | Expr Id -> Bool
exprIsTrivial Expr Id
a = Expr Id -> Bool
want_eta Expr Id
e
want_eta (Var {}) = Bool
False
want_eta (Lit {}) = Bool
False
want_eta Expr Id
_ = Bool
True
abstractFloats :: UnfoldingOpts -> TopLevelFlag -> [OutTyVar] -> SimplFloats
-> OutExpr -> SimplM ([OutBind], OutExpr)
abstractFloats :: UnfoldingOpts
-> TopLevelFlag
-> [Id]
-> SimplFloats
-> Expr Id
-> SimplM ([Bind Id], Expr Id)
abstractFloats UnfoldingOpts
uf_opts TopLevelFlag
top_lvl [Id]
main_tvs SimplFloats
floats Expr Id
body
= Bool -> SimplM ([Bind Id], Expr Id) -> SimplM ([Bind Id], Expr Id)
forall a. HasCallStack => Bool -> a -> a
assert ([Bind Id] -> Bool
forall (f :: * -> *) a. Foldable f => f a -> Bool
notNull [Bind Id]
body_floats) (SimplM ([Bind Id], Expr Id) -> SimplM ([Bind Id], Expr Id))
-> SimplM ([Bind Id], Expr Id) -> SimplM ([Bind Id], Expr Id)
forall a b. (a -> b) -> a -> b
$
Bool -> SimplM ([Bind Id], Expr Id) -> SimplM ([Bind Id], Expr Id)
forall a. HasCallStack => Bool -> a -> a
assert (OrdList (Bind Id) -> Bool
forall a. OrdList a -> Bool
isNilOL (SimplFloats -> OrdList (Bind Id)
sfJoinFloats SimplFloats
floats)) (SimplM ([Bind Id], Expr Id) -> SimplM ([Bind Id], Expr Id))
-> SimplM ([Bind Id], Expr Id) -> SimplM ([Bind Id], Expr Id)
forall a b. (a -> b) -> a -> b
$
do { (Subst
subst, [Bind Id]
float_binds) <- (Subst -> Bind Id -> SimplM (Subst, Bind Id))
-> Subst -> [Bind Id] -> SimplM (Subst, [Bind Id])
forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM Subst -> Bind Id -> SimplM (Subst, Bind Id)
abstract Subst
empty_subst [Bind Id]
body_floats
; ([Bind Id], Expr Id) -> SimplM ([Bind Id], Expr Id)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Bind Id]
float_binds, (() :: Constraint) => Subst -> Expr Id -> Expr Id
Subst -> Expr Id -> Expr Id
GHC.Core.Subst.substExpr Subst
subst Expr Id
body) }
where
is_top_lvl :: Bool
is_top_lvl = TopLevelFlag -> Bool
isTopLevel TopLevelFlag
top_lvl
body_floats :: [Bind Id]
body_floats = LetFloats -> [Bind Id]
letFloatBinds (SimplFloats -> LetFloats
sfLetFloats SimplFloats
floats)
empty_subst :: Subst
empty_subst = InScopeSet -> Subst
GHC.Core.Subst.mkEmptySubst (SimplFloats -> InScopeSet
sfInScope SimplFloats
floats)
abstract :: GHC.Core.Subst.Subst -> OutBind -> SimplM (GHC.Core.Subst.Subst, OutBind)
abstract :: Subst -> Bind Id -> SimplM (Subst, Bind Id)
abstract Subst
subst (NonRec Id
id Expr Id
rhs)
= do { (Id
poly_id1, Expr Id
poly_app) <- [Id] -> Id -> SimplM (Id, Expr Id)
mk_poly1 [Id]
tvs_here Id
id
; let (Id
poly_id2, Expr Id
poly_rhs) = Id -> [Id] -> Expr Id -> (Id, Expr Id)
mk_poly2 Id
poly_id1 [Id]
tvs_here Expr Id
rhs'
!subst' :: Subst
subst' = Subst -> Id -> Expr Id -> Subst
GHC.Core.Subst.extendIdSubst Subst
subst Id
id Expr Id
poly_app
; (Subst, Bind Id) -> SimplM (Subst, Bind Id)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Subst
subst', Id -> Expr Id -> Bind Id
forall b. b -> Expr b -> Bind b
NonRec Id
poly_id2 Expr Id
poly_rhs) }
where
rhs' :: Expr Id
rhs' = (() :: Constraint) => Subst -> Expr Id -> Expr Id
Subst -> Expr Id -> Expr Id
GHC.Core.Subst.substExpr Subst
subst Expr Id
rhs
tvs_here :: [Id]
tvs_here = (Id -> Bool) -> [Id] -> [Id]
forall a. (a -> Bool) -> [a] -> [a]
filter (Id -> TyCoVarSet -> Bool
`elemVarSet` TyCoVarSet
free_tvs) [Id]
main_tvs
free_tvs :: TyCoVarSet
free_tvs = TyCoVarSet -> TyCoVarSet
closeOverKinds (TyCoVarSet -> TyCoVarSet) -> TyCoVarSet -> TyCoVarSet
forall a b. (a -> b) -> a -> b
$
(Id -> Bool) -> Expr Id -> TyCoVarSet
exprSomeFreeVars Id -> Bool
isTyVar Expr Id
rhs'
abstract Subst
subst (Rec [(Id, Expr Id)]
prs)
= do { ([Id]
poly_ids, [Expr Id]
poly_apps) <- (Id -> SimplM (Id, Expr Id)) -> [Id] -> SimplM ([Id], [Expr Id])
forall (m :: * -> *) a b c.
Applicative m =>
(a -> m (b, c)) -> [a] -> m ([b], [c])
mapAndUnzipM ([Id] -> Id -> SimplM (Id, Expr Id)
mk_poly1 [Id]
tvs_here) [Id]
ids
; let subst' :: Subst
subst' = Subst -> [(Id, Expr Id)] -> Subst
GHC.Core.Subst.extendSubstList Subst
subst ([Id]
ids [Id] -> [Expr Id] -> [(Id, Expr Id)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [Expr Id]
poly_apps)
poly_pairs :: [(Id, Expr Id)]
poly_pairs = [ Id -> [Id] -> Expr Id -> (Id, Expr Id)
mk_poly2 Id
poly_id [Id]
tvs_here Expr Id
rhs'
| (Id
poly_id, Expr Id
rhs) <- [Id]
poly_ids [Id] -> [Expr Id] -> [(Id, Expr Id)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [Expr Id]
rhss
, let rhs' :: Expr Id
rhs' = (() :: Constraint) => Subst -> Expr Id -> Expr Id
Subst -> Expr Id -> Expr Id
GHC.Core.Subst.substExpr Subst
subst' Expr Id
rhs ]
; (Subst, Bind Id) -> SimplM (Subst, Bind Id)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Subst
subst', [(Id, Expr Id)] -> Bind Id
forall b. [(b, Expr b)] -> Bind b
Rec [(Id, Expr Id)]
poly_pairs) }
where
([Id]
ids,[Expr Id]
rhss) = [(Id, Expr Id)] -> ([Id], [Expr Id])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Id, Expr Id)]
prs
tvs_here :: [Id]
tvs_here = [Id] -> [Id]
scopedSort [Id]
main_tvs
mk_poly1 :: [TyVar] -> Id -> SimplM (Id, CoreExpr)
mk_poly1 :: [Id] -> Id -> SimplM (Id, Expr Id)
mk_poly1 [Id]
tvs_here Id
var
= do { Unique
uniq <- SimplM Unique
forall (m :: * -> *). MonadUnique m => m Unique
getUniqueM
; let poly_name :: Name
poly_name = Name -> Unique -> Name
setNameUnique (Id -> Name
idName Id
var) Unique
uniq
poly_ty :: OutType
poly_ty = [Id] -> OutType -> OutType
mkInfForAllTys [Id]
tvs_here (Id -> OutType
idType Id
var)
poly_id :: Id
poly_id = Id -> [Id] -> Id -> Id
transferPolyIdInfo Id
var [Id]
tvs_here (Id -> Id) -> Id -> Id
forall a b. (a -> b) -> a -> b
$
(() :: Constraint) => Name -> OutType -> OutType -> Id
Name -> OutType -> OutType -> Id
mkLocalId Name
poly_name (Id -> OutType
idMult Id
var) OutType
poly_ty
; (Id, Expr Id) -> SimplM (Id, Expr Id)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Id
poly_id, Expr Id -> [OutType] -> Expr Id
forall b. Expr b -> [OutType] -> Expr b
mkTyApps (Id -> Expr Id
forall b. Id -> Expr b
Var Id
poly_id) ([Id] -> [OutType]
mkTyVarTys [Id]
tvs_here)) }
mk_poly2 :: Id -> [TyVar] -> CoreExpr -> (Id, CoreExpr)
mk_poly2 :: Id -> [Id] -> Expr Id -> (Id, Expr Id)
mk_poly2 Id
poly_id [Id]
tvs_here Expr Id
rhs
= (Id
poly_id Id -> Unfolding -> Id
`setIdUnfolding` Unfolding
unf, Expr Id
poly_rhs)
where
poly_rhs :: Expr Id
poly_rhs = [Id] -> Expr Id -> Expr Id
forall b. [b] -> Expr b -> Expr b
mkLams [Id]
tvs_here Expr Id
rhs
unf :: Unfolding
unf = UnfoldingOpts
-> UnfoldingSource
-> Bool
-> Bool
-> Expr Id
-> Maybe UnfoldingCache
-> Unfolding
mkUnfolding UnfoldingOpts
uf_opts UnfoldingSource
InlineRhs Bool
is_top_lvl Bool
False Expr Id
poly_rhs Maybe UnfoldingCache
forall a. Maybe a
Nothing
prepareAlts :: OutExpr -> InId -> [InAlt] -> SimplM ([AltCon], [InAlt])
prepareAlts :: Expr Id -> Id -> [InAlt] -> SimplM ([AltCon], [InAlt])
prepareAlts Expr Id
scrut Id
case_bndr [InAlt]
alts
| Just (TyCon
tc, [OutType]
tys) <- (() :: Constraint) => OutType -> Maybe (TyCon, [OutType])
OutType -> Maybe (TyCon, [OutType])
splitTyConApp_maybe (Id -> OutType
idType Id
case_bndr)
= do { [Unique]
us <- SimplM [Unique]
forall (m :: * -> *). MonadUnique m => m [Unique]
getUniquesM
; let ([AltCon]
idcs1, [InAlt]
alts1) = TyCon -> [OutType] -> [AltCon] -> [InAlt] -> ([AltCon], [InAlt])
forall b.
TyCon -> [OutType] -> [AltCon] -> [Alt b] -> ([AltCon], [Alt b])
filterAlts TyCon
tc [OutType]
tys [AltCon]
imposs_cons [InAlt]
alts
(Bool
yes2, [InAlt]
alts2) = [Unique]
-> OutType
-> TyCon
-> [OutType]
-> [AltCon]
-> [InAlt]
-> (Bool, [InAlt])
refineDefaultAlt [Unique]
us (Id -> OutType
idMult Id
case_bndr) TyCon
tc [OutType]
tys [AltCon]
idcs1 [InAlt]
alts1
(Bool
yes3, [AltCon]
idcs3, [InAlt]
alts3) = [AltCon] -> [InAlt] -> (Bool, [AltCon], [InAlt])
combineIdenticalAlts [AltCon]
idcs1 [InAlt]
alts2
; Bool -> SimplM () -> SimplM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
yes2 (SimplM () -> SimplM ()) -> SimplM () -> SimplM ()
forall a b. (a -> b) -> a -> b
$ Tick -> SimplM ()
tick (Id -> Tick
FillInCaseDefault Id
case_bndr)
; Bool -> SimplM () -> SimplM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
yes3 (SimplM () -> SimplM ()) -> SimplM () -> SimplM ()
forall a b. (a -> b) -> a -> b
$ Tick -> SimplM ()
tick (Id -> Tick
AltMerge Id
case_bndr)
; ([AltCon], [InAlt]) -> SimplM ([AltCon], [InAlt])
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return ([AltCon]
idcs3, [InAlt]
alts3) }
| Bool
otherwise
= ([AltCon], [InAlt]) -> SimplM ([AltCon], [InAlt])
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return ([], [InAlt]
alts)
where
imposs_cons :: [AltCon]
imposs_cons = case Expr Id
scrut of
Var Id
v -> Unfolding -> [AltCon]
otherCons (Id -> Unfolding
idUnfolding Id
v)
Expr Id
_ -> []
mkCase, mkCase1, mkCase2, mkCase3
:: DynFlags
-> OutExpr -> OutId
-> OutType -> [OutAlt]
-> SimplM OutExpr
mkCase :: DynFlags -> Expr Id -> Id -> OutType -> [InAlt] -> SimplM (Expr Id)
mkCase DynFlags
dflags Expr Id
scrut Id
outer_bndr OutType
alts_ty (Alt AltCon
DEFAULT [Id]
_ Expr Id
deflt_rhs : [InAlt]
outer_alts)
| GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_CaseMerge DynFlags
dflags
, ([CoreTickish]
ticks, Case (Var Id
inner_scrut_var) Id
inner_bndr OutType
_ [InAlt]
inner_alts)
<- (CoreTickish -> Bool) -> Expr Id -> ([CoreTickish], Expr Id)
forall b.
(CoreTickish -> Bool) -> Expr b -> ([CoreTickish], Expr b)
stripTicksTop CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishFloatable Expr Id
deflt_rhs
, Id
inner_scrut_var Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
outer_bndr
= do { Tick -> SimplM ()
tick (Id -> Tick
CaseMerge Id
outer_bndr)
; let wrap_alt :: InAlt -> InAlt
wrap_alt (Alt AltCon
con [Id]
args Expr Id
rhs) = Bool -> InAlt -> InAlt
forall a. HasCallStack => Bool -> a -> a
assert (Id
outer_bndr Id -> [Id] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Id]
args)
(AltCon -> [Id] -> Expr Id -> InAlt
forall b. AltCon -> [b] -> Expr b -> Alt b
Alt AltCon
con [Id]
args (Expr Id -> Expr Id
wrap_rhs Expr Id
rhs))
wrap_rhs :: Expr Id -> Expr Id
wrap_rhs Expr Id
rhs = Bind Id -> Expr Id -> Expr Id
forall b. Bind b -> Expr b -> Expr b
Let (Id -> Expr Id -> Bind Id
forall b. b -> Expr b -> Bind b
NonRec Id
inner_bndr (Id -> Expr Id
forall b. Id -> Expr b
Var Id
outer_bndr)) Expr Id
rhs
wrapped_alts :: [InAlt]
wrapped_alts | Id -> Bool
isDeadBinder Id
inner_bndr = [InAlt]
inner_alts
| Bool
otherwise = (InAlt -> InAlt) -> [InAlt] -> [InAlt]
forall a b. (a -> b) -> [a] -> [b]
map InAlt -> InAlt
wrap_alt [InAlt]
inner_alts
merged_alts :: [InAlt]
merged_alts = [InAlt] -> [InAlt] -> [InAlt]
forall a. [Alt a] -> [Alt a] -> [Alt a]
mergeAlts [InAlt]
outer_alts [InAlt]
wrapped_alts
; (Expr Id -> Expr Id) -> SimplM (Expr Id) -> SimplM (Expr Id)
forall a b. (a -> b) -> SimplM a -> SimplM b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([CoreTickish] -> Expr Id -> Expr Id
mkTicks [CoreTickish]
ticks) (SimplM (Expr Id) -> SimplM (Expr Id))
-> SimplM (Expr Id) -> SimplM (Expr Id)
forall a b. (a -> b) -> a -> b
$
DynFlags -> Expr Id -> Id -> OutType -> [InAlt] -> SimplM (Expr Id)
mkCase1 DynFlags
dflags Expr Id
scrut Id
outer_bndr OutType
alts_ty [InAlt]
merged_alts
}
mkCase DynFlags
dflags Expr Id
scrut Id
bndr OutType
alts_ty [InAlt]
alts = DynFlags -> Expr Id -> Id -> OutType -> [InAlt] -> SimplM (Expr Id)
mkCase1 DynFlags
dflags Expr Id
scrut Id
bndr OutType
alts_ty [InAlt]
alts
mkCase1 :: DynFlags -> Expr Id -> Id -> OutType -> [InAlt] -> SimplM (Expr Id)
mkCase1 DynFlags
_dflags Expr Id
scrut Id
case_bndr OutType
_ alts :: [InAlt]
alts@(Alt AltCon
_ [Id]
_ Expr Id
rhs1 : [InAlt]
_)
| (InAlt -> Bool) -> [InAlt] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all InAlt -> Bool
identity_alt [InAlt]
alts
= do { Tick -> SimplM ()
tick (Id -> Tick
CaseIdentity Id
case_bndr)
; Expr Id -> SimplM (Expr Id)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return ([CoreTickish] -> Expr Id -> Expr Id
mkTicks [CoreTickish]
ticks (Expr Id -> Expr Id) -> Expr Id -> Expr Id
forall a b. (a -> b) -> a -> b
$ Expr Id -> Expr Id -> Expr Id
forall {b} {b}. Expr b -> Expr b -> Expr b
re_cast Expr Id
scrut Expr Id
rhs1) }
where
ticks :: [CoreTickish]
ticks = (InAlt -> [CoreTickish]) -> [InAlt] -> [CoreTickish]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(Alt AltCon
_ [Id]
_ Expr Id
rhs) -> (CoreTickish -> Bool) -> Expr Id -> [CoreTickish]
forall b. (CoreTickish -> Bool) -> Expr b -> [CoreTickish]
stripTicksT CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishFloatable Expr Id
rhs) ([InAlt] -> [InAlt]
forall a. HasCallStack => [a] -> [a]
tail [InAlt]
alts)
identity_alt :: InAlt -> Bool
identity_alt (Alt AltCon
con [Id]
args Expr Id
rhs) = Expr Id -> AltCon -> [Id] -> Bool
check_eq Expr Id
rhs AltCon
con [Id]
args
check_eq :: Expr Id -> AltCon -> [Id] -> Bool
check_eq (Cast Expr Id
rhs OutCoercion
co) AltCon
con [Id]
args
= Bool -> Bool
not ((Id -> Bool) -> [Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Id -> TyCoVarSet -> Bool
`elemVarSet` OutCoercion -> TyCoVarSet
tyCoVarsOfCo OutCoercion
co) [Id]
args) Bool -> Bool -> Bool
&& Expr Id -> AltCon -> [Id] -> Bool
check_eq Expr Id
rhs AltCon
con [Id]
args
check_eq (Tick CoreTickish
t Expr Id
e) AltCon
alt [Id]
args
= CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishFloatable CoreTickish
t Bool -> Bool -> Bool
&& Expr Id -> AltCon -> [Id] -> Bool
check_eq Expr Id
e AltCon
alt [Id]
args
check_eq (Lit Literal
lit) (LitAlt Literal
lit') [Id]
_ = Literal
lit Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== Literal
lit'
check_eq (Var Id
v) AltCon
_ [Id]
_ | Id
v Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
case_bndr = Bool
True
check_eq (Var Id
v) (DataAlt DataCon
con) [Id]
args
| [OutType] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [OutType]
arg_tys, [Id] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Id]
args = Id
v Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== DataCon -> Id
dataConWorkId DataCon
con
check_eq Expr Id
rhs (DataAlt DataCon
con) [Id]
args = (CoreTickish -> Bool) -> Expr Id -> Expr Id -> Bool
forall b. (CoreTickish -> Bool) -> Expr b -> Expr b -> Bool
cheapEqExpr' CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishFloatable Expr Id
rhs (Expr Id -> Bool) -> Expr Id -> Bool
forall a b. (a -> b) -> a -> b
$
DataCon -> [OutType] -> [Id] -> Expr Id
forall b. DataCon -> [OutType] -> [Id] -> Expr b
mkConApp2 DataCon
con [OutType]
arg_tys [Id]
args
check_eq Expr Id
_ AltCon
_ [Id]
_ = Bool
False
arg_tys :: [OutType]
arg_tys = HasCallStack => OutType -> [OutType]
OutType -> [OutType]
tyConAppArgs (Id -> OutType
idType Id
case_bndr)
re_cast :: Expr b -> Expr b -> Expr b
re_cast Expr b
scrut (Cast Expr b
rhs OutCoercion
co) = Expr b -> OutCoercion -> Expr b
forall b. Expr b -> OutCoercion -> Expr b
Cast (Expr b -> Expr b -> Expr b
re_cast Expr b
scrut Expr b
rhs) OutCoercion
co
re_cast Expr b
scrut Expr b
_ = Expr b
scrut
mkCase1 DynFlags
dflags Expr Id
scrut Id
bndr OutType
alts_ty [InAlt]
alts = DynFlags -> Expr Id -> Id -> OutType -> [InAlt] -> SimplM (Expr Id)
mkCase2 DynFlags
dflags Expr Id
scrut Id
bndr OutType
alts_ty [InAlt]
alts
mkCase2 :: DynFlags -> Expr Id -> Id -> OutType -> [InAlt] -> SimplM (Expr Id)
mkCase2 DynFlags
dflags Expr Id
scrut Id
bndr OutType
alts_ty [InAlt]
alts
|
case [InAlt]
alts of
[Alt AltCon
DEFAULT [Id]
_ Expr Id
_] -> Bool
False
[InAlt]
_ -> Bool
True
, GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_CaseFolding DynFlags
dflags
, Just (Expr Id
scrut', AltCon -> Maybe AltCon
tx_con, Id -> Expr Id
mk_orig) <- Platform
-> Expr Id
-> Maybe (Expr Id, AltCon -> Maybe AltCon, Id -> Expr Id)
caseRules (DynFlags -> Platform
targetPlatform DynFlags
dflags) Expr Id
scrut
= do { Id
bndr' <- FastString -> OutType -> OutType -> SimplM Id
newId (String -> FastString
fsLit String
"lwild") OutType
Many ((() :: Constraint) => Expr Id -> OutType
Expr Id -> OutType
exprType Expr Id
scrut')
; [InAlt]
alts' <- (InAlt -> SimplM (Maybe InAlt)) -> [InAlt] -> SimplM [InAlt]
forall (m :: * -> *) a b.
Applicative m =>
(a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeM ((AltCon -> Maybe AltCon)
-> (Id -> Expr Id) -> Id -> InAlt -> SimplM (Maybe InAlt)
tx_alt AltCon -> Maybe AltCon
tx_con Id -> Expr Id
mk_orig Id
bndr') [InAlt]
alts
; DynFlags -> Expr Id -> Id -> OutType -> [InAlt] -> SimplM (Expr Id)
mkCase3 DynFlags
dflags Expr Id
scrut' Id
bndr' OutType
alts_ty ([InAlt] -> SimplM (Expr Id)) -> [InAlt] -> SimplM (Expr Id)
forall a b. (a -> b) -> a -> b
$
[InAlt] -> [InAlt]
add_default ([InAlt] -> [InAlt]
re_sort [InAlt]
alts')
}
| Bool
otherwise
= DynFlags -> Expr Id -> Id -> OutType -> [InAlt] -> SimplM (Expr Id)
mkCase3 DynFlags
dflags Expr Id
scrut Id
bndr OutType
alts_ty [InAlt]
alts
where
tx_alt :: (AltCon -> Maybe AltCon) -> (Id -> CoreExpr) -> Id
-> CoreAlt -> SimplM (Maybe CoreAlt)
tx_alt :: (AltCon -> Maybe AltCon)
-> (Id -> Expr Id) -> Id -> InAlt -> SimplM (Maybe InAlt)
tx_alt AltCon -> Maybe AltCon
tx_con Id -> Expr Id
mk_orig Id
new_bndr (Alt AltCon
con [Id]
bs Expr Id
rhs)
= case AltCon -> Maybe AltCon
tx_con AltCon
con of
Maybe AltCon
Nothing -> Maybe InAlt -> SimplM (Maybe InAlt)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe InAlt
forall a. Maybe a
Nothing
Just AltCon
con' -> do { [Id]
bs' <- Id -> AltCon -> SimplM [Id]
forall {m :: * -> *}. MonadUnique m => Id -> AltCon -> m [Id]
mk_new_bndrs Id
new_bndr AltCon
con'
; Maybe InAlt -> SimplM (Maybe InAlt)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return (InAlt -> Maybe InAlt
forall a. a -> Maybe a
Just (AltCon -> [Id] -> Expr Id -> InAlt
forall b. AltCon -> [b] -> Expr b -> Alt b
Alt AltCon
con' [Id]
bs' Expr Id
rhs')) }
where
rhs' :: Expr Id
rhs' | Id -> Bool
isDeadBinder Id
bndr = Expr Id
rhs
| Bool
otherwise = Id -> Expr Id -> Expr Id -> Expr Id
bindNonRec Id
bndr Expr Id
orig_val Expr Id
rhs
orig_val :: Expr Id
orig_val = case AltCon
con of
AltCon
DEFAULT -> Id -> Expr Id
mk_orig Id
new_bndr
LitAlt Literal
l -> Literal -> Expr Id
forall b. Literal -> Expr b
Lit Literal
l
DataAlt DataCon
dc -> DataCon -> [OutType] -> [Id] -> Expr Id
forall b. DataCon -> [OutType] -> [Id] -> Expr b
mkConApp2 DataCon
dc (HasCallStack => OutType -> [OutType]
OutType -> [OutType]
tyConAppArgs (Id -> OutType
idType Id
bndr)) [Id]
bs
mk_new_bndrs :: Id -> AltCon -> m [Id]
mk_new_bndrs Id
new_bndr (DataAlt DataCon
dc)
| Bool -> Bool
not (DataCon -> Bool
isNullaryRepDataCon DataCon
dc)
=
do { [Unique]
us <- m [Unique]
forall (m :: * -> *). MonadUnique m => m [Unique]
getUniquesM
; let ([Id]
ex_tvs, [Id]
arg_ids) = [Unique] -> OutType -> DataCon -> [OutType] -> ([Id], [Id])
dataConRepInstPat [Unique]
us (Id -> OutType
idMult Id
new_bndr) DataCon
dc
(HasCallStack => OutType -> [OutType]
OutType -> [OutType]
tyConAppArgs (Id -> OutType
idType Id
new_bndr))
; [Id] -> m [Id]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Id]
ex_tvs [Id] -> [Id] -> [Id]
forall a. [a] -> [a] -> [a]
++ [Id]
arg_ids) }
mk_new_bndrs Id
_ AltCon
_ = [Id] -> m [Id]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return []
re_sort :: [CoreAlt] -> [CoreAlt]
re_sort :: [InAlt] -> [InAlt]
re_sort [InAlt]
alts = (InAlt -> InAlt -> Ordering) -> [InAlt] -> [InAlt]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy InAlt -> InAlt -> Ordering
forall a. Alt a -> Alt a -> Ordering
cmpAlt [InAlt]
alts
add_default :: [CoreAlt] -> [CoreAlt]
add_default :: [InAlt] -> [InAlt]
add_default (Alt (LitAlt {}) [Id]
bs Expr Id
rhs : [InAlt]
alts) = AltCon -> [Id] -> Expr Id -> InAlt
forall b. AltCon -> [b] -> Expr b -> Alt b
Alt AltCon
DEFAULT [Id]
bs Expr Id
rhs InAlt -> [InAlt] -> [InAlt]
forall a. a -> [a] -> [a]
: [InAlt]
alts
add_default [InAlt]
alts = [InAlt]
alts
mkCase3 :: DynFlags -> Expr Id -> Id -> OutType -> [InAlt] -> SimplM (Expr Id)
mkCase3 DynFlags
_dflags Expr Id
scrut Id
bndr OutType
alts_ty [InAlt]
alts
= Expr Id -> SimplM (Expr Id)
forall a. a -> SimplM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Expr Id -> Id -> OutType -> [InAlt] -> Expr Id
forall b. Expr b -> b -> OutType -> [Alt b] -> Expr b
Case Expr Id
scrut Id
bndr OutType
alts_ty [InAlt]
alts)
isExitJoinId :: Var -> Bool
isExitJoinId :: Id -> Bool
isExitJoinId Id
id
= Id -> Bool
isJoinId Id
id
Bool -> Bool -> Bool
&& OccInfo -> Bool
isOneOcc (Id -> OccInfo
idOccInfo Id
id)
Bool -> Bool -> Bool
&& OccInfo -> InsideLam
occ_in_lam (Id -> OccInfo
idOccInfo Id
id) InsideLam -> InsideLam -> Bool
forall a. Eq a => a -> a -> Bool
== InsideLam
IsInsideLam