{-# LANGUAGE CPP #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wno-incomplete-record-updates -Wno-incomplete-uni-patterns #-}
module GHC.Core.Opt.Simplify ( simplTopBinds, simplExpr, simplRules ) where
#include "HsVersions.h"
import GHC.Prelude
import GHC.Platform
import GHC.Driver.Session
import GHC.Driver.Ppr
import GHC.Driver.Config
import GHC.Core.Opt.Simplify.Monad
import GHC.Core.Type hiding ( substTy, substTyVar, extendTvSubst, extendCvSubst )
import GHC.Core.Opt.Simplify.Env
import GHC.Core.Opt.Simplify.Utils
import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr )
import GHC.Types.Literal   ( litIsLifted ) 
import GHC.Types.SourceText
import GHC.Types.Id
import GHC.Types.Id.Make   ( seqId )
import GHC.Core.Make       ( FloatBind, mkImpossibleExpr, castBottomExpr )
import qualified GHC.Core.Make
import GHC.Types.Id.Info
import GHC.Types.Name           ( mkSystemVarName, isExternalName, getOccFS )
import GHC.Core.Coercion hiding ( substCo, substCoVar )
import GHC.Core.Coercion.Opt    ( optCoercion )
import GHC.Core.FamInstEnv      ( FamInstEnv, topNormaliseType_maybe )
import GHC.Core.DataCon
   ( DataCon, dataConWorkId, dataConRepStrictness
   , dataConRepArgTys, isUnboxedTupleDataCon
   , StrictnessMark (..) )
import GHC.Core.Opt.Monad ( Tick(..), SimplMode(..) )
import GHC.Core
import GHC.Builtin.Types.Prim( realWorldStatePrimTy )
import GHC.Builtin.Names( runRWKey )
import GHC.Types.Demand ( StrictSig(..), Demand, dmdTypeDepth, isStrUsedDmd
                        , mkClosedStrictSig, topDmd, seqDmd, isDeadEndDiv )
import GHC.Types.Cpr    ( mkCprSig, botCpr )
import GHC.Core.Ppr     ( pprCoreExpr )
import GHC.Types.Unique ( hasKey )
import GHC.Core.Unfold
import GHC.Core.Unfold.Make
import GHC.Core.Utils
import GHC.Core.Opt.Arity ( ArityType(..)
                          , pushCoTyArg, pushCoValArg
                          , idArityType, etaExpandAT )
import GHC.Core.SimpleOpt ( exprIsConApp_maybe, joinPointBinding_maybe, joinPointBindings_maybe )
import GHC.Core.FVs     ( mkRuleInfo )
import GHC.Core.Rules   ( lookupRule, getRules, initRuleOpts )
import GHC.Types.Basic
import GHC.Utils.Monad  ( mapAccumLM, liftIO )
import GHC.Utils.Logger
import GHC.Types.Tickish
import GHC.Types.Var    ( isTyCoVar )
import GHC.Data.Maybe   ( isNothing, orElse )
import Control.Monad
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Data.FastString
import GHC.Utils.Misc
import GHC.Unit.Module ( moduleName, pprModuleName )
import GHC.Core.Multiplicity
import GHC.Builtin.PrimOps ( PrimOp (SeqOp) )
simplTopBinds :: SimplEnv -> [InBind] -> SimplM (SimplFloats, SimplEnv)
simplTopBinds :: SimplEnv -> [InBind] -> SimplM (SimplFloats, SimplEnv)
simplTopBinds SimplEnv
env0 [InBind]
binds0
  = do  {       
                
                
                
                
        
        ; !SimplEnv
env1 <- {-#SCC "simplTopBinds-simplRecBndrs" #-} SimplEnv -> [OutId] -> SimplM SimplEnv
simplRecBndrs SimplEnv
env0 ([InBind] -> [OutId]
forall b. [Bind b] -> [b]
bindersOfBinds [InBind]
binds0)
        ; (SimplFloats
floats, SimplEnv
env2) <- {-#SCC "simplTopBinds-simpl_binds" #-} SimplEnv -> [InBind] -> SimplM (SimplFloats, SimplEnv)
simpl_binds SimplEnv
env1 [InBind]
binds0
        ; Tick -> SimplM ()
freeTick Tick
SimplifierDone
        ; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, SimplEnv
env2) }
  where
        
        
        
        
    simpl_binds :: SimplEnv -> [InBind] -> SimplM (SimplFloats, SimplEnv)
    simpl_binds :: SimplEnv -> [InBind] -> SimplM (SimplFloats, SimplEnv)
simpl_binds SimplEnv
env []           = (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv
env)
    simpl_binds SimplEnv
env (InBind
bind:[InBind]
binds) = do { (SimplFloats
float,  SimplEnv
env1) <- SimplEnv -> InBind -> SimplM (SimplFloats, SimplEnv)
simpl_bind SimplEnv
env InBind
bind
                                      ; (SimplFloats
floats, SimplEnv
env2) <- SimplEnv -> [InBind] -> SimplM (SimplFloats, SimplEnv)
simpl_binds SimplEnv
env1 [InBind]
binds
                                      
                                      ; let !floats1 :: SimplFloats
floats1 = SimplFloats
float SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats
                                      ; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1, SimplEnv
env2) }
    simpl_bind :: SimplEnv -> InBind -> SimplM (SimplFloats, SimplEnv)
simpl_bind SimplEnv
env (Rec [(OutId, CoreExpr)]
pairs)
      = SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> [(OutId, CoreExpr)]
-> SimplM (SimplFloats, SimplEnv)
simplRecBind SimplEnv
env TopLevelFlag
TopLevel MaybeJoinCont
forall a. Maybe a
Nothing [(OutId, CoreExpr)]
pairs
    simpl_bind SimplEnv
env (NonRec OutId
b CoreExpr
r)
      = do { (SimplEnv
env', OutId
b') <- SimplEnv
-> OutId -> OutId -> MaybeJoinCont -> SimplM (SimplEnv, OutId)
addBndrRules SimplEnv
env OutId
b (SimplEnv -> OutId -> OutId
lookupRecBndr SimplEnv
env OutId
b) MaybeJoinCont
forall a. Maybe a
Nothing
           ; SimplEnv
-> TopLevelFlag
-> RecFlag
-> MaybeJoinCont
-> OutId
-> OutId
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
simplRecOrTopPair SimplEnv
env' TopLevelFlag
TopLevel RecFlag
NonRecursive MaybeJoinCont
forall a. Maybe a
Nothing OutId
b OutId
b' CoreExpr
r }
simplRecBind :: SimplEnv -> TopLevelFlag -> MaybeJoinCont
             -> [(InId, InExpr)]
             -> SimplM (SimplFloats, SimplEnv)
simplRecBind :: SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> [(OutId, CoreExpr)]
-> SimplM (SimplFloats, SimplEnv)
simplRecBind SimplEnv
env0 TopLevelFlag
top_lvl MaybeJoinCont
mb_cont [(OutId, CoreExpr)]
pairs0
  = do  { (SimplEnv
env_with_info, [(OutId, OutId, CoreExpr)]
triples) <- (SimplEnv
 -> (OutId, CoreExpr)
 -> SimplM (SimplEnv, (OutId, OutId, CoreExpr)))
-> SimplEnv
-> [(OutId, CoreExpr)]
-> SimplM (SimplEnv, [(OutId, OutId, CoreExpr)])
forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM SimplEnv
-> (OutId, CoreExpr) -> SimplM (SimplEnv, (OutId, OutId, CoreExpr))
add_rules SimplEnv
env0 [(OutId, CoreExpr)]
pairs0
        ; (SimplFloats
rec_floats, SimplEnv
env1) <- SimplEnv
-> [(OutId, OutId, CoreExpr)] -> SimplM (SimplFloats, SimplEnv)
go SimplEnv
env_with_info [(OutId, OutId, CoreExpr)]
triples
        ; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats -> SimplFloats
mkRecFloats SimplFloats
rec_floats, SimplEnv
env1) }
  where
    add_rules :: SimplEnv -> (InBndr,InExpr) -> SimplM (SimplEnv, (InBndr, OutBndr, InExpr))
        
    add_rules :: SimplEnv
-> (OutId, CoreExpr) -> SimplM (SimplEnv, (OutId, OutId, CoreExpr))
add_rules SimplEnv
env (OutId
bndr, CoreExpr
rhs)
        = do { (SimplEnv
env', OutId
bndr') <- SimplEnv
-> OutId -> OutId -> MaybeJoinCont -> SimplM (SimplEnv, OutId)
addBndrRules SimplEnv
env OutId
bndr (SimplEnv -> OutId -> OutId
lookupRecBndr SimplEnv
env OutId
bndr) MaybeJoinCont
mb_cont
             ; (SimplEnv, (OutId, OutId, CoreExpr))
-> SimplM (SimplEnv, (OutId, OutId, CoreExpr))
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv
env', (OutId
bndr, OutId
bndr', CoreExpr
rhs)) }
    go :: SimplEnv
-> [(OutId, OutId, CoreExpr)] -> SimplM (SimplFloats, SimplEnv)
go SimplEnv
env [] = (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv
env)
    go SimplEnv
env ((OutId
old_bndr, OutId
new_bndr, CoreExpr
rhs) : [(OutId, OutId, CoreExpr)]
pairs)
        = do { (SimplFloats
float, SimplEnv
env1) <- SimplEnv
-> TopLevelFlag
-> RecFlag
-> MaybeJoinCont
-> OutId
-> OutId
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
simplRecOrTopPair SimplEnv
env TopLevelFlag
top_lvl RecFlag
Recursive MaybeJoinCont
mb_cont
                                                  OutId
old_bndr OutId
new_bndr CoreExpr
rhs
             ; (SimplFloats
floats, SimplEnv
env2) <- SimplEnv
-> [(OutId, OutId, CoreExpr)] -> SimplM (SimplFloats, SimplEnv)
go SimplEnv
env1 [(OutId, OutId, CoreExpr)]
pairs
             ; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
float SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats, SimplEnv
env2) }
simplRecOrTopPair :: SimplEnv
                  -> TopLevelFlag -> RecFlag -> MaybeJoinCont
                  -> InId -> OutBndr -> InExpr  
                  -> SimplM (SimplFloats, SimplEnv)
simplRecOrTopPair :: SimplEnv
-> TopLevelFlag
-> RecFlag
-> MaybeJoinCont
-> OutId
-> OutId
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
simplRecOrTopPair SimplEnv
env TopLevelFlag
top_lvl RecFlag
is_rec MaybeJoinCont
mb_cont OutId
old_bndr OutId
new_bndr CoreExpr
rhs
  | Just SimplEnv
env' <- SimplEnv
-> TopLevelFlag -> OutId -> CoreExpr -> SimplEnv -> Maybe SimplEnv
preInlineUnconditionally SimplEnv
env TopLevelFlag
top_lvl OutId
old_bndr CoreExpr
rhs SimplEnv
env
  = {-#SCC "simplRecOrTopPair-pre-inline-uncond" #-}
    [Char]
-> SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
trace_bind [Char]
"pre-inline-uncond" (SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv))
-> SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall a b. (a -> b) -> a -> b
$
    do { Tick -> SimplM ()
tick (OutId -> Tick
PreInlineUnconditionally OutId
old_bndr)
       ; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return ( SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv
env' ) }
  | Just SimplCont
cont <- MaybeJoinCont
mb_cont
  = {-#SCC "simplRecOrTopPair-join" #-}
    ASSERT( isNotTopLevel top_lvl && isJoinId new_bndr )
    [Char]
-> SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
trace_bind [Char]
"join" (SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv))
-> SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall a b. (a -> b) -> a -> b
$
    SimplEnv
-> SimplCont
-> OutId
-> OutId
-> CoreExpr
-> SimplEnv
-> SimplM (SimplFloats, SimplEnv)
simplJoinBind SimplEnv
env SimplCont
cont OutId
old_bndr OutId
new_bndr CoreExpr
rhs SimplEnv
env
  | Bool
otherwise
  = {-#SCC "simplRecOrTopPair-normal" #-}
    [Char]
-> SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
trace_bind [Char]
"normal" (SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv))
-> SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall a b. (a -> b) -> a -> b
$
    SimplEnv
-> TopLevelFlag
-> RecFlag
-> OutId
-> OutId
-> CoreExpr
-> SimplEnv
-> SimplM (SimplFloats, SimplEnv)
simplLazyBind SimplEnv
env TopLevelFlag
top_lvl RecFlag
is_rec OutId
old_bndr OutId
new_bndr CoreExpr
rhs SimplEnv
env
  where
    dflags :: DynFlags
dflags = SimplEnv -> DynFlags
seDynFlags SimplEnv
env
    logger :: Logger
logger = SimplEnv -> Logger
seLogger SimplEnv
env
    
    
    trace_bind :: [Char]
-> SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
trace_bind [Char]
what SimplM (SimplFloats, SimplEnv)
thing_inside
      | Bool -> Bool
not (DumpFlag -> DynFlags -> Bool
dopt DumpFlag
Opt_D_verbose_core2core DynFlags
dflags)
      = SimplM (SimplFloats, SimplEnv)
thing_inside
      | Bool
otherwise
      = Logger -> TraceAction (SimplM (SimplFloats, SimplEnv))
forall a. Logger -> TraceAction a
putTraceMsg Logger
logger DynFlags
dflags ([Char]
"SimplBind " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
what)
         (OutId -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutId
old_bndr) SimplM (SimplFloats, SimplEnv)
thing_inside
simplLazyBind :: SimplEnv
              -> TopLevelFlag -> RecFlag
              -> InId -> OutId          
                                        
                                        
                                        
              -> InExpr -> SimplEnv     
              -> SimplM (SimplFloats, SimplEnv)
simplLazyBind :: SimplEnv
-> TopLevelFlag
-> RecFlag
-> OutId
-> OutId
-> CoreExpr
-> SimplEnv
-> SimplM (SimplFloats, SimplEnv)
simplLazyBind SimplEnv
env TopLevelFlag
top_lvl RecFlag
is_rec OutId
bndr OutId
bndr1 CoreExpr
rhs SimplEnv
rhs_se
  = ASSERT( isId bndr )
    ASSERT2( not (isJoinId bndr), ppr bndr )
    
    do  { let   !rhs_env :: SimplEnv
rhs_env     = SimplEnv
rhs_se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env 
                ([OutId]
tvs, CoreExpr
body) = case CoreExpr -> ([OutId], [OutId], CoreExpr)
collectTyAndValBinders CoreExpr
rhs of
                                ([OutId]
tvs, [], CoreExpr
body)
                                  | CoreExpr -> Bool
forall {b}. Expr b -> Bool
surely_not_lam CoreExpr
body -> ([OutId]
tvs, CoreExpr
body)
                                ([OutId], [OutId], CoreExpr)
_                       -> ([], CoreExpr
rhs)
                surely_not_lam :: Expr b -> Bool
surely_not_lam (Lam {})     = Bool
False
                surely_not_lam (Tick CoreTickish
t Expr b
e)
                  | Bool -> Bool
not (CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishFloatable CoreTickish
t) = Expr b -> Bool
surely_not_lam Expr b
e
                   
                surely_not_lam Expr b
_            = Bool
True
                        
                        
                        
                        
        ; (SimplEnv
body_env, [OutId]
tvs') <- {-#SCC "simplBinders" #-} SimplEnv -> [OutId] -> SimplM (SimplEnv, [OutId])
simplBinders SimplEnv
rhs_env [OutId]
tvs
                
        
        ; let rhs_cont :: SimplCont
rhs_cont = Kind -> SimplCont
mkRhsStop (SimplEnv -> Kind -> Kind
substTy SimplEnv
body_env (CoreExpr -> Kind
exprType CoreExpr
body))
        ; (SimplFloats
body_floats0, CoreExpr
body0) <- {-#SCC "simplExprF" #-} SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
body_env CoreExpr
body SimplCont
rhs_cont
              
              
              
        ; let (SimplFloats
body_floats1, CoreExpr
body1) = SimplFloats -> CoreExpr -> (SimplFloats, CoreExpr)
wrapJoinFloatsX SimplFloats
body_floats0 CoreExpr
body0
        
        
        ; let body_env1 :: SimplEnv
body_env1 = SimplEnv
body_env SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
body_floats1
              
              
        ; (LetFloats
let_floats, OutId
bndr2, CoreExpr
body2) <- {-#SCC "prepareBinding" #-}
                                        SimplEnv
-> TopLevelFlag
-> OutId
-> OutId
-> CoreExpr
-> SimplM (LetFloats, OutId, CoreExpr)
prepareBinding SimplEnv
body_env1 TopLevelFlag
top_lvl OutId
bndr OutId
bndr1 CoreExpr
body1
        ; let body_floats2 :: SimplFloats
body_floats2 = SimplFloats
body_floats1 SimplFloats -> LetFloats -> SimplFloats
`addLetFloats` LetFloats
let_floats
        ; (SimplFloats
rhs_floats, CoreExpr
body3)
            <-  if Bool -> Bool
not (TopLevelFlag -> RecFlag -> Bool -> SimplFloats -> CoreExpr -> Bool
doFloatFromRhs TopLevelFlag
top_lvl RecFlag
is_rec Bool
False SimplFloats
body_floats2 CoreExpr
body2)
                then                    
                     (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplFloats -> CoreExpr -> CoreExpr
wrapFloats SimplFloats
body_floats2 CoreExpr
body1)
                else if [OutId] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [OutId]
tvs then   
                     {-#SCC "simplLazyBind-simple-floating" #-}
                     do { Tick -> SimplM ()
tick Tick
LetFloatFromLet
                        ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
body_floats2, CoreExpr
body2) }
                else                    
                     {-#SCC "simplLazyBind-type-abstraction-first" #-}
                     do { Tick -> SimplM ()
tick Tick
LetFloatFromLet
                        ; ([InBind]
poly_binds, CoreExpr
body3) <- UnfoldingOpts
-> TopLevelFlag
-> [OutId]
-> SimplFloats
-> CoreExpr
-> SimplM ([InBind], CoreExpr)
abstractFloats (SimplEnv -> UnfoldingOpts
seUnfoldingOpts SimplEnv
env) TopLevelFlag
top_lvl
                                                                [OutId]
tvs' SimplFloats
body_floats2 CoreExpr
body2
                        ; let floats :: SimplFloats
floats = (SimplFloats -> InBind -> SimplFloats)
-> SimplFloats -> [InBind] -> SimplFloats
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' SimplFloats -> InBind -> SimplFloats
extendFloats (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env) [InBind]
poly_binds
                        ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, CoreExpr
body3) }
        ; let env' :: SimplEnv
env' = SimplEnv
env SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
rhs_floats
        ; CoreExpr
rhs' <- SimplEnv -> [OutId] -> CoreExpr -> SimplCont -> SimplM CoreExpr
mkLam SimplEnv
env' [OutId]
tvs' CoreExpr
body3 SimplCont
rhs_cont
        ; (SimplFloats
bind_float, SimplEnv
env2) <- SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> OutId
-> OutId
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
completeBind SimplEnv
env' TopLevelFlag
top_lvl MaybeJoinCont
forall a. Maybe a
Nothing OutId
bndr OutId
bndr2 CoreExpr
rhs'
        ; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
rhs_floats SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
bind_float, SimplEnv
env2) }
simplJoinBind :: SimplEnv
              -> SimplCont
              -> InId -> OutId          
                                        
                                        
              -> InExpr -> SimplEnv     
              -> SimplM (SimplFloats, SimplEnv)
simplJoinBind :: SimplEnv
-> SimplCont
-> OutId
-> OutId
-> CoreExpr
-> SimplEnv
-> SimplM (SimplFloats, SimplEnv)
simplJoinBind SimplEnv
env SimplCont
cont OutId
old_bndr OutId
new_bndr CoreExpr
rhs SimplEnv
rhs_se
  = do  { let rhs_env :: SimplEnv
rhs_env = SimplEnv
rhs_se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env
        ; CoreExpr
rhs' <- SimplEnv -> OutId -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplJoinRhs SimplEnv
rhs_env OutId
old_bndr CoreExpr
rhs SimplCont
cont
        ; SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> OutId
-> OutId
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
completeBind SimplEnv
env TopLevelFlag
NotTopLevel (SimplCont -> MaybeJoinCont
forall a. a -> Maybe a
Just SimplCont
cont) OutId
old_bndr OutId
new_bndr CoreExpr
rhs' }
simplNonRecX :: SimplEnv
             -> InId            
             -> OutExpr         
             -> SimplM (SimplFloats, SimplEnv)
simplNonRecX :: SimplEnv -> OutId -> CoreExpr -> SimplM (SimplFloats, SimplEnv)
simplNonRecX SimplEnv
env OutId
bndr CoreExpr
new_rhs
  | ASSERT2( not (isJoinId bndr), ppr bndr )
    OutId -> Bool
isDeadBinder OutId
bndr   
  = (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv
env)    
                                         
  | Coercion Coercion
co <- CoreExpr
new_rhs
  = (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv -> OutId -> Coercion -> SimplEnv
extendCvSubst SimplEnv
env OutId
bndr Coercion
co)
  | Bool
otherwise
  = do  { (SimplEnv
env', OutId
bndr') <- SimplEnv -> OutId -> SimplM (SimplEnv, OutId)
simplBinder SimplEnv
env OutId
bndr
        ; TopLevelFlag
-> SimplEnv
-> Bool
-> OutId
-> OutId
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
completeNonRecX TopLevelFlag
NotTopLevel SimplEnv
env' (OutId -> Bool
isStrictId OutId
bndr') OutId
bndr OutId
bndr' CoreExpr
new_rhs }
          
          
          
          
          
          
completeNonRecX :: TopLevelFlag -> SimplEnv
                -> Bool
                -> InId                 
                -> OutId                
                -> OutExpr              
                -> SimplM (SimplFloats, SimplEnv)    
completeNonRecX :: TopLevelFlag
-> SimplEnv
-> Bool
-> OutId
-> OutId
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
completeNonRecX TopLevelFlag
top_lvl SimplEnv
env Bool
is_strict OutId
old_bndr OutId
new_bndr CoreExpr
new_rhs
  = ASSERT2( not (isJoinId new_bndr), ppr new_bndr )
    do  { (LetFloats
prepd_floats, OutId
new_bndr, CoreExpr
new_rhs)
              <- SimplEnv
-> TopLevelFlag
-> OutId
-> OutId
-> CoreExpr
-> SimplM (LetFloats, OutId, CoreExpr)
prepareBinding SimplEnv
env TopLevelFlag
top_lvl OutId
old_bndr OutId
new_bndr CoreExpr
new_rhs
        ; let floats :: SimplFloats
floats = SimplEnv -> SimplFloats
emptyFloats SimplEnv
env SimplFloats -> LetFloats -> SimplFloats
`addLetFloats` LetFloats
prepd_floats
        ; (SimplFloats
rhs_floats, CoreExpr
rhs2) <-
                if TopLevelFlag -> RecFlag -> Bool -> SimplFloats -> CoreExpr -> Bool
doFloatFromRhs TopLevelFlag
NotTopLevel RecFlag
NonRecursive Bool
is_strict SimplFloats
floats CoreExpr
new_rhs
                then    
                     do { Tick -> SimplM ()
tick Tick
LetFloatFromLet
                        ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, CoreExpr
new_rhs) }
                else    
                     (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplFloats -> CoreExpr -> CoreExpr
wrapFloats SimplFloats
floats CoreExpr
new_rhs)
        ; (SimplFloats
bind_float, SimplEnv
env2) <- SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> OutId
-> OutId
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
completeBind (SimplEnv
env SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
rhs_floats)
                                             TopLevelFlag
NotTopLevel MaybeJoinCont
forall a. Maybe a
Nothing
                                             OutId
old_bndr OutId
new_bndr CoreExpr
rhs2
        ; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
rhs_floats SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
bind_float, SimplEnv
env2) }
prepareBinding :: SimplEnv -> TopLevelFlag
               -> InId -> OutId -> OutExpr
               -> SimplM (LetFloats, OutId, OutExpr)
prepareBinding :: SimplEnv
-> TopLevelFlag
-> OutId
-> OutId
-> CoreExpr
-> SimplM (LetFloats, OutId, CoreExpr)
prepareBinding SimplEnv
env TopLevelFlag
top_lvl OutId
old_bndr OutId
bndr CoreExpr
rhs
  | Cast CoreExpr
rhs1 Coercion
co <- CoreExpr
rhs
    
    
  , Bool -> Bool
not (Unfolding -> Bool
isStableUnfolding (OutId -> Unfolding
realIdUnfolding OutId
old_bndr))
        
  , Bool -> Bool
not (CoreExpr -> Bool
exprIsTrivial CoreExpr
rhs1)
        
  , let ty1 :: Kind
ty1 = Coercion -> Kind
coercionLKind Coercion
co
  , Bool -> Bool
not (HasDebugCallStack => Kind -> Bool
Kind -> Bool
isUnliftedType Kind
ty1)
        
  = do { (LetFloats
floats, OutId
new_id) <- SimplMode
-> TopLevelFlag
-> FastString
-> IdInfo
-> CoreExpr
-> Kind
-> SimplM (LetFloats, OutId)
makeTrivialBinding (SimplEnv -> SimplMode
getMode SimplEnv
env) TopLevelFlag
top_lvl
                                   (OutId -> FastString
forall a. NamedThing a => a -> FastString
getOccFS OutId
bndr) IdInfo
worker_info CoreExpr
rhs1 Kind
ty1
       ; let bndr' :: OutId
bndr' = OutId
bndr OutId -> InlinePragma -> OutId
`setInlinePragma` InlinePragma -> InlinePragma
mkCastWrapperInlinePrag (OutId -> InlinePragma
idInlinePragma OutId
bndr)
       ; (LetFloats, OutId, CoreExpr) -> SimplM (LetFloats, OutId, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
floats, OutId
bndr', CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast (OutId -> CoreExpr
forall b. OutId -> Expr b
Var OutId
new_id) Coercion
co) }
  | Bool
otherwise
  = do { (LetFloats
floats, CoreExpr
rhs') <- SimplMode
-> TopLevelFlag
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
prepareRhs (SimplEnv -> SimplMode
getMode SimplEnv
env) TopLevelFlag
top_lvl (OutId -> FastString
forall a. NamedThing a => a -> FastString
getOccFS OutId
bndr) CoreExpr
rhs
       ; (LetFloats, OutId, CoreExpr) -> SimplM (LetFloats, OutId, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
floats, OutId
bndr, CoreExpr
rhs') }
 where
   info :: IdInfo
info = HasDebugCallStack => OutId -> IdInfo
OutId -> IdInfo
idInfo OutId
bndr
   worker_info :: IdInfo
worker_info = IdInfo
vanillaIdInfo IdInfo -> StrictSig -> IdInfo
`setStrictnessInfo` IdInfo -> StrictSig
strictnessInfo IdInfo
info
                               IdInfo -> CprSig -> IdInfo
`setCprInfo`        IdInfo -> CprSig
cprInfo IdInfo
info
                               IdInfo -> Demand -> IdInfo
`setDemandInfo`     IdInfo -> Demand
demandInfo IdInfo
info
                               IdInfo -> InlinePragma -> IdInfo
`setInlinePragInfo` IdInfo -> InlinePragma
inlinePragInfo IdInfo
info
                               IdInfo -> Int -> IdInfo
`setArityInfo`      IdInfo -> Int
arityInfo IdInfo
info
          
          
mkCastWrapperInlinePrag :: InlinePragma -> InlinePragma
mkCastWrapperInlinePrag :: InlinePragma -> InlinePragma
mkCastWrapperInlinePrag (InlinePragma { inl_act :: InlinePragma -> Activation
inl_act = Activation
act, inl_rule :: InlinePragma -> RuleMatchInfo
inl_rule = RuleMatchInfo
rule_info })
  = InlinePragma { inl_src :: SourceText
inl_src    = [Char] -> SourceText
SourceText [Char]
"{-# INLINE"
                 , inl_inline :: InlineSpec
inl_inline = InlineSpec
NoUserInlinePrag 
                 , inl_sat :: Maybe Int
inl_sat    = Maybe Int
forall a. Maybe a
Nothing      
                 , inl_act :: Activation
inl_act    = Activation
wrap_act     
                 , inl_rule :: RuleMatchInfo
inl_rule   = RuleMatchInfo
rule_info }  
                                
  where
    
    
    wrap_act :: Activation
wrap_act | Activation -> Bool
isNeverActive Activation
act = Activation
activateDuringFinal
             | Bool
otherwise         = Activation
act
prepareRhs :: SimplMode -> TopLevelFlag
           -> FastString    
           -> OutExpr
           -> SimplM (LetFloats, OutExpr)
prepareRhs :: SimplMode
-> TopLevelFlag
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
prepareRhs SimplMode
mode TopLevelFlag
top_lvl FastString
occ CoreExpr
rhs0
  = do  { (Bool
_is_exp, LetFloats
floats, CoreExpr
rhs1) <- Int -> CoreExpr -> SimplM (Bool, LetFloats, CoreExpr)
go Int
0 CoreExpr
rhs0
        ; (LetFloats, CoreExpr) -> SimplM (LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
floats, CoreExpr
rhs1) }
  where
    go :: Int -> OutExpr -> SimplM (Bool, LetFloats, OutExpr)
    go :: Int -> CoreExpr -> SimplM (Bool, LetFloats, CoreExpr)
go Int
n_val_args (Cast CoreExpr
rhs Coercion
co)
        = do { (Bool
is_exp, LetFloats
floats, CoreExpr
rhs') <- Int -> CoreExpr -> SimplM (Bool, LetFloats, CoreExpr)
go Int
n_val_args CoreExpr
rhs
             ; (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
is_exp, LetFloats
floats, CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
rhs' Coercion
co) }
    go Int
n_val_args (App CoreExpr
fun (Type Kind
ty))
        = do { (Bool
is_exp, LetFloats
floats, CoreExpr
rhs') <- Int -> CoreExpr -> SimplM (Bool, LetFloats, CoreExpr)
go Int
n_val_args CoreExpr
fun
             ; (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
is_exp, LetFloats
floats, CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App CoreExpr
rhs' (Kind -> CoreExpr
forall b. Kind -> Expr b
Type Kind
ty)) }
    go Int
n_val_args (App CoreExpr
fun CoreExpr
arg)
        = do { (Bool
is_exp, LetFloats
floats1, CoreExpr
fun') <- Int -> CoreExpr -> SimplM (Bool, LetFloats, CoreExpr)
go (Int
n_val_argsInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) CoreExpr
fun
             ; case Bool
is_exp of
                Bool
False -> (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, LetFloats
emptyLetFloats, CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App CoreExpr
fun CoreExpr
arg)
                Bool
True  -> do { (LetFloats
floats2, CoreExpr
arg') <- SimplMode
-> TopLevelFlag
-> Demand
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
makeTrivial SimplMode
mode TopLevelFlag
top_lvl Demand
topDmd FastString
occ CoreExpr
arg
                            ; (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True, LetFloats
floats1 LetFloats -> LetFloats -> LetFloats
`addLetFlts` LetFloats
floats2, CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App CoreExpr
fun' CoreExpr
arg') } }
    go Int
n_val_args (Var OutId
fun)
        = (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
is_exp, LetFloats
emptyLetFloats, OutId -> CoreExpr
forall b. OutId -> Expr b
Var OutId
fun)
        where
          is_exp :: Bool
is_exp = CheapAppFun
isExpandableApp OutId
fun Int
n_val_args   
                        
                        
                        
    go Int
n_val_args (Tick CoreTickish
t CoreExpr
rhs)
        
        
        | CoreTickish -> TickishScoping
forall (pass :: TickishPass). GenTickish pass -> TickishScoping
tickishScoped CoreTickish
t TickishScoping -> TickishScoping -> Bool
forall a. Eq a => a -> a -> Bool
== TickishScoping
NoScope
        = do { (Bool
is_exp, LetFloats
floats, CoreExpr
rhs') <- Int -> CoreExpr -> SimplM (Bool, LetFloats, CoreExpr)
go Int
n_val_args CoreExpr
rhs
             ; (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
is_exp, LetFloats
floats, CoreTickish -> CoreExpr -> CoreExpr
forall b. CoreTickish -> Expr b -> Expr b
Tick CoreTickish
t CoreExpr
rhs') }
        
        
        
        | (Bool -> Bool
not (CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishCounts CoreTickish
t) Bool -> Bool -> Bool
|| CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishCanSplit CoreTickish
t)
        = do { (Bool
is_exp, LetFloats
floats, CoreExpr
rhs') <- Int -> CoreExpr -> SimplM (Bool, LetFloats, CoreExpr)
go Int
n_val_args CoreExpr
rhs
             ; let tickIt :: (OutId, CoreExpr) -> (OutId, CoreExpr)
tickIt (OutId
id, CoreExpr
expr) = (OutId
id, CoreTickish -> CoreExpr -> CoreExpr
mkTick (CoreTickish -> CoreTickish
forall (pass :: TickishPass). GenTickish pass -> GenTickish pass
mkNoCount CoreTickish
t) CoreExpr
expr)
                   floats' :: LetFloats
floats' = LetFloats -> ((OutId, CoreExpr) -> (OutId, CoreExpr)) -> LetFloats
mapLetFloats LetFloats
floats (OutId, CoreExpr) -> (OutId, CoreExpr)
tickIt
             ; (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
is_exp, LetFloats
floats', CoreTickish -> CoreExpr -> CoreExpr
forall b. CoreTickish -> Expr b -> Expr b
Tick CoreTickish
t CoreExpr
rhs') }
    go Int
_ CoreExpr
other
        = (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, LetFloats
emptyLetFloats, CoreExpr
other)
makeTrivialArg :: SimplMode -> ArgSpec -> SimplM (LetFloats, ArgSpec)
makeTrivialArg :: SimplMode -> ArgSpec -> SimplM (LetFloats, ArgSpec)
makeTrivialArg SimplMode
mode arg :: ArgSpec
arg@(ValArg { as_arg :: ArgSpec -> CoreExpr
as_arg = CoreExpr
e, as_dmd :: ArgSpec -> Demand
as_dmd = Demand
dmd })
  = do { (LetFloats
floats, CoreExpr
e') <- SimplMode
-> TopLevelFlag
-> Demand
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
makeTrivial SimplMode
mode TopLevelFlag
NotTopLevel Demand
dmd ([Char] -> FastString
fsLit [Char]
"arg") CoreExpr
e
       ; (LetFloats, ArgSpec) -> SimplM (LetFloats, ArgSpec)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
floats, ArgSpec
arg { as_arg :: CoreExpr
as_arg = CoreExpr
e' }) }
makeTrivialArg SimplMode
_ ArgSpec
arg
  = (LetFloats, ArgSpec) -> SimplM (LetFloats, ArgSpec)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
emptyLetFloats, ArgSpec
arg)  
makeTrivial :: SimplMode -> TopLevelFlag -> Demand
            -> FastString  
            -> OutExpr     
            -> SimplM (LetFloats, OutExpr)
makeTrivial :: SimplMode
-> TopLevelFlag
-> Demand
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
makeTrivial SimplMode
mode TopLevelFlag
top_lvl Demand
dmd FastString
occ_fs CoreExpr
expr
  | CoreExpr -> Bool
exprIsTrivial CoreExpr
expr                          
  Bool -> Bool -> Bool
|| Bool -> Bool
not (TopLevelFlag -> CoreExpr -> Kind -> Bool
bindingOk TopLevelFlag
top_lvl CoreExpr
expr Kind
expr_ty)       
                                                
  = (LetFloats, CoreExpr) -> SimplM (LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
emptyLetFloats, CoreExpr
expr)
  | Cast CoreExpr
expr' Coercion
co <- CoreExpr
expr
  = do { (LetFloats
floats, CoreExpr
triv_expr) <- SimplMode
-> TopLevelFlag
-> Demand
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
makeTrivial SimplMode
mode TopLevelFlag
top_lvl Demand
dmd FastString
occ_fs CoreExpr
expr'
       ; (LetFloats, CoreExpr) -> SimplM (LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
floats, CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
triv_expr Coercion
co) }
  | Bool
otherwise
  = do { (LetFloats
floats, OutId
new_id) <- SimplMode
-> TopLevelFlag
-> FastString
-> IdInfo
-> CoreExpr
-> Kind
-> SimplM (LetFloats, OutId)
makeTrivialBinding SimplMode
mode TopLevelFlag
top_lvl FastString
occ_fs
                                                IdInfo
id_info CoreExpr
expr Kind
expr_ty
       ; (LetFloats, CoreExpr) -> SimplM (LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
floats, OutId -> CoreExpr
forall b. OutId -> Expr b
Var OutId
new_id) }
  where
    id_info :: IdInfo
id_info = IdInfo
vanillaIdInfo IdInfo -> Demand -> IdInfo
`setDemandInfo` Demand
dmd
    expr_ty :: Kind
expr_ty = CoreExpr -> Kind
exprType CoreExpr
expr
makeTrivialBinding :: SimplMode -> TopLevelFlag
                   -> FastString  
                   -> IdInfo
                   -> OutExpr     
                   -> OutType     
                   -> SimplM (LetFloats, OutId)
makeTrivialBinding :: SimplMode
-> TopLevelFlag
-> FastString
-> IdInfo
-> CoreExpr
-> Kind
-> SimplM (LetFloats, OutId)
makeTrivialBinding SimplMode
mode TopLevelFlag
top_lvl FastString
occ_fs IdInfo
info CoreExpr
expr Kind
expr_ty
  = do  { (LetFloats
floats, CoreExpr
expr1) <- SimplMode
-> TopLevelFlag
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
prepareRhs SimplMode
mode TopLevelFlag
top_lvl FastString
occ_fs CoreExpr
expr
        ; Unique
uniq <- SimplM Unique
forall (m :: * -> *). MonadUnique m => m Unique
getUniqueM
        ; let name :: Name
name = Unique -> FastString -> Name
mkSystemVarName Unique
uniq FastString
occ_fs
              var :: OutId
var  = HasDebugCallStack => Name -> Kind -> Kind -> IdInfo -> OutId
Name -> Kind -> Kind -> IdInfo -> OutId
mkLocalIdWithInfo Name
name Kind
Many Kind
expr_ty IdInfo
info
        
        
        ; (ArityType
arity_type, CoreExpr
expr2) <- SimplMode -> OutId -> CoreExpr -> SimplM (ArityType, CoreExpr)
tryEtaExpandRhs SimplMode
mode OutId
var CoreExpr
expr1
          
          
          
        ; Unfolding
unf <- UnfoldingOpts
-> TopLevelFlag
-> UnfoldingSource
-> OutId
-> CoreExpr
-> SimplM Unfolding
mkLetUnfolding (SimplMode -> UnfoldingOpts
sm_uf_opts SimplMode
mode) TopLevelFlag
top_lvl UnfoldingSource
InlineRhs OutId
var CoreExpr
expr2
        ; let final_id :: OutId
final_id = OutId -> ArityType -> Unfolding -> OutId
addLetBndrInfo OutId
var ArityType
arity_type Unfolding
unf
              bind :: InBind
bind     = OutId -> CoreExpr -> InBind
forall b. b -> Expr b -> Bind b
NonRec OutId
final_id CoreExpr
expr2
        ; (LetFloats, OutId) -> SimplM (LetFloats, OutId)
forall (m :: * -> *) a. Monad m => a -> m a
return ( LetFloats
floats LetFloats -> LetFloats -> LetFloats
`addLetFlts` InBind -> LetFloats
unitLetFloat InBind
bind, OutId
final_id ) }
bindingOk :: TopLevelFlag -> CoreExpr -> Type -> Bool
bindingOk :: TopLevelFlag -> CoreExpr -> Kind -> Bool
bindingOk TopLevelFlag
top_lvl CoreExpr
expr Kind
expr_ty
  | TopLevelFlag -> Bool
isTopLevel TopLevelFlag
top_lvl = CoreExpr -> Kind -> Bool
exprIsTopLevelBindable CoreExpr
expr Kind
expr_ty
  | Bool
otherwise          = Bool
True
completeBind :: SimplEnv
             -> TopLevelFlag            
             -> MaybeJoinCont           
             -> InId                    
             -> OutId -> OutExpr        
             -> SimplM (SimplFloats, SimplEnv)
completeBind :: SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> OutId
-> OutId
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
completeBind SimplEnv
env TopLevelFlag
top_lvl MaybeJoinCont
mb_cont OutId
old_bndr OutId
new_bndr CoreExpr
new_rhs
 | OutId -> Bool
isCoVar OutId
old_bndr
 = case CoreExpr
new_rhs of
     Coercion Coercion
co -> (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv -> OutId -> Coercion -> SimplEnv
extendCvSubst SimplEnv
env OutId
old_bndr Coercion
co)
     CoreExpr
_           -> (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> InBind -> (SimplFloats, SimplEnv)
mkFloatBind SimplEnv
env (OutId -> CoreExpr -> InBind
forall b. b -> Expr b -> Bind b
NonRec OutId
new_bndr CoreExpr
new_rhs))
 | Bool
otherwise
 = ASSERT( isId new_bndr )
   do { let old_info :: IdInfo
old_info = HasDebugCallStack => OutId -> IdInfo
OutId -> IdInfo
idInfo OutId
old_bndr
            old_unf :: Unfolding
old_unf  = IdInfo -> Unfolding
unfoldingInfo IdInfo
old_info
            occ_info :: OccInfo
occ_info = IdInfo -> OccInfo
occInfo IdInfo
old_info
         
         
      ; (ArityType
new_arity, CoreExpr
final_rhs) <- SimplMode -> OutId -> CoreExpr -> SimplM (ArityType, CoreExpr)
tryEtaExpandRhs (SimplEnv -> SimplMode
getMode SimplEnv
env) OutId
new_bndr CoreExpr
new_rhs
        
      ; Unfolding
new_unfolding <- SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> OutId
-> CoreExpr
-> Kind
-> ArityType
-> Unfolding
-> SimplM Unfolding
simplLetUnfolding SimplEnv
env TopLevelFlag
top_lvl MaybeJoinCont
mb_cont OutId
old_bndr
                          CoreExpr
final_rhs (OutId -> Kind
idType OutId
new_bndr) ArityType
new_arity Unfolding
old_unf
      ; let final_bndr :: OutId
final_bndr = OutId -> ArityType -> Unfolding -> OutId
addLetBndrInfo OutId
new_bndr ArityType
new_arity Unfolding
new_unfolding
        
      ; if SimplEnv -> TopLevelFlag -> OutId -> OccInfo -> CoreExpr -> Bool
postInlineUnconditionally SimplEnv
env TopLevelFlag
top_lvl OutId
final_bndr OccInfo
occ_info CoreExpr
final_rhs
        then 
             do  { Tick -> SimplM ()
tick (OutId -> Tick
PostInlineUnconditionally OutId
old_bndr)
                 ; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return ( SimplEnv -> SimplFloats
emptyFloats SimplEnv
env
                          , SimplEnv -> OutId -> SimplSR -> SimplEnv
extendIdSubst SimplEnv
env OutId
old_bndr (SimplSR -> SimplEnv) -> SimplSR -> SimplEnv
forall a b. (a -> b) -> a -> b
$
                            CoreExpr -> Maybe Int -> SimplSR
DoneEx CoreExpr
final_rhs (OutId -> Maybe Int
isJoinId_maybe OutId
new_bndr)) }
                
                
        else 
             
             (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> InBind -> (SimplFloats, SimplEnv)
mkFloatBind SimplEnv
env (OutId -> CoreExpr -> InBind
forall b. b -> Expr b -> Bind b
NonRec OutId
final_bndr CoreExpr
final_rhs)) }
addLetBndrInfo :: OutId -> ArityType -> Unfolding -> OutId
addLetBndrInfo :: OutId -> ArityType -> Unfolding -> OutId
addLetBndrInfo OutId
new_bndr ArityType
new_arity_type Unfolding
new_unf
  = OutId
new_bndr OutId -> IdInfo -> OutId
`setIdInfo` IdInfo
info5
  where
    AT [OneShotInfo]
oss Divergence
div = ArityType
new_arity_type
    new_arity :: Int
new_arity  = [OneShotInfo] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [OneShotInfo]
oss
    info1 :: IdInfo
info1 = HasDebugCallStack => OutId -> IdInfo
OutId -> IdInfo
idInfo OutId
new_bndr IdInfo -> Int -> IdInfo
`setArityInfo` Int
new_arity
    
    info2 :: IdInfo
info2 = IdInfo
info1 IdInfo -> Unfolding -> IdInfo
`setUnfoldingInfo` Unfolding
new_unf
    
    
    
    
    info3 :: IdInfo
info3 | Unfolding -> Bool
isEvaldUnfolding Unfolding
new_unf
            Bool -> Bool -> Bool
|| (case IdInfo -> StrictSig
strictnessInfo IdInfo
info2 of
                  StrictSig DmdType
dmd_ty -> Int
new_arity Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< DmdType -> Int
dmdTypeDepth DmdType
dmd_ty)
          = IdInfo -> Maybe IdInfo
zapDemandInfo IdInfo
info2 Maybe IdInfo -> IdInfo -> IdInfo
forall a. Maybe a -> a -> a
`orElse` IdInfo
info2
          | Bool
otherwise
          = IdInfo
info2
    
    info4 :: IdInfo
info4 | Divergence -> Bool
isDeadEndDiv Divergence
div = IdInfo
info3 IdInfo -> StrictSig -> IdInfo
`setStrictnessInfo` StrictSig
bot_sig
                                     IdInfo -> CprSig -> IdInfo
`setCprInfo`        CprSig
bot_cpr
          | Bool
otherwise        = IdInfo
info3
    bot_sig :: StrictSig
bot_sig = [Demand] -> Divergence -> StrictSig
mkClosedStrictSig (Int -> Demand -> [Demand]
forall a. Int -> a -> [a]
replicate Int
new_arity Demand
topDmd) Divergence
div
    bot_cpr :: CprSig
bot_cpr = Int -> Cpr -> CprSig
mkCprSig Int
new_arity Cpr
botCpr
     
     
     
    info5 :: IdInfo
info5 = IdInfo -> IdInfo
zapCallArityInfo IdInfo
info4
simplExpr :: SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr :: SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr !SimplEnv
env (Type Kind
ty) 
  = do { Kind
ty' <- SimplEnv -> Kind -> SimplM Kind
simplType SimplEnv
env Kind
ty  
       ; CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (Kind -> CoreExpr
forall b. Kind -> Expr b
Type Kind
ty') }
simplExpr SimplEnv
env CoreExpr
expr
  = SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
env CoreExpr
expr (Kind -> SimplCont
mkBoringStop Kind
expr_out_ty)
  where
    expr_out_ty :: OutType
    expr_out_ty :: Kind
expr_out_ty = SimplEnv -> Kind -> Kind
substTy SimplEnv
env (CoreExpr -> Kind
exprType CoreExpr
expr)
    
    
simplExprC :: SimplEnv
           -> InExpr     
           -> SimplCont
           -> SimplM OutExpr
        
simplExprC :: SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
env CoreExpr
expr SimplCont
cont
  = 
    do  { (SimplFloats
floats, CoreExpr
expr') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
expr SimplCont
cont
        ; 
          
          
          CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> SimplM CoreExpr) -> CoreExpr -> SimplM CoreExpr
forall a b. (a -> b) -> a -> b
$! SimplFloats -> CoreExpr -> CoreExpr
wrapFloats SimplFloats
floats CoreExpr
expr' }
simplExprF :: SimplEnv
           -> InExpr     
           -> SimplCont
           -> SimplM (SimplFloats, OutExpr)
simplExprF :: SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF !SimplEnv
env CoreExpr
e !SimplCont
cont 
  = 
    SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF1 SimplEnv
env CoreExpr
e SimplCont
cont
simplExprF1 :: SimplEnv -> InExpr -> SimplCont
            -> SimplM (SimplFloats, OutExpr)
simplExprF1 :: SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF1 SimplEnv
_ (Type Kind
ty) SimplCont
cont
  = [Char] -> SDoc -> SimplM (SimplFloats, CoreExpr)
forall a. HasCallStack => [Char] -> SDoc -> a
pprPanic [Char]
"simplExprF: type" (Kind -> SDoc
forall a. Outputable a => a -> SDoc
ppr Kind
ty SDoc -> SDoc -> SDoc
<+> [Char] -> SDoc
text[Char]
"cont: " SDoc -> SDoc -> SDoc
<+> SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
cont)
    
    
    
simplExprF1 SimplEnv
env (Var OutId
v)        SimplCont
cont = {-#SCC "simplIdF" #-} SimplEnv -> OutId -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplIdF SimplEnv
env OutId
v SimplCont
cont
simplExprF1 SimplEnv
env (Lit Literal
lit)      SimplCont
cont = {-#SCC "rebuild" #-} SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
lit) SimplCont
cont
simplExprF1 SimplEnv
env (Tick CoreTickish
t CoreExpr
expr)  SimplCont
cont = {-#SCC "simplTick" #-} SimplEnv
-> CoreTickish
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplTick SimplEnv
env CoreTickish
t CoreExpr
expr SimplCont
cont
simplExprF1 SimplEnv
env (Cast CoreExpr
body Coercion
co) SimplCont
cont = {-#SCC "simplCast" #-} SimplEnv
-> CoreExpr
-> Coercion
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplCast SimplEnv
env CoreExpr
body Coercion
co SimplCont
cont
simplExprF1 SimplEnv
env (Coercion Coercion
co)  SimplCont
cont = {-#SCC "simplCoercionF" #-} SimplEnv -> Coercion -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplCoercionF SimplEnv
env Coercion
co SimplCont
cont
simplExprF1 SimplEnv
env (App CoreExpr
fun CoreExpr
arg) SimplCont
cont
  = {-#SCC "simplExprF1-App" #-} case CoreExpr
arg of
      Type Kind
ty -> do { 
                      
                      
                      Kind
arg' <- SimplEnv -> Kind -> SimplM Kind
simplType SimplEnv
env Kind
ty
                      
                      
                      
                    ; let hole' :: Kind
hole' = SimplEnv -> Kind -> Kind
substTy SimplEnv
env (CoreExpr -> Kind
exprType CoreExpr
fun)
                    ; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
fun (SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplCont -> SimplM (SimplFloats, CoreExpr)
forall a b. (a -> b) -> a -> b
$
                      ApplyToTy { sc_arg_ty :: Kind
sc_arg_ty  = Kind
arg'
                                , sc_hole_ty :: Kind
sc_hole_ty = Kind
hole'
                                , sc_cont :: SimplCont
sc_cont    = SimplCont
cont } }
      CoreExpr
_       ->
          
          
          
          
          
          
          
          
        SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
fun (SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplCont -> SimplM (SimplFloats, CoreExpr)
forall a b. (a -> b) -> a -> b
$
        ApplyToVal { sc_arg :: CoreExpr
sc_arg = CoreExpr
arg, sc_env :: SimplEnv
sc_env = SimplEnv
env
                   , sc_hole_ty :: Kind
sc_hole_ty = SimplEnv -> Kind -> Kind
substTy SimplEnv
env (CoreExpr -> Kind
exprType CoreExpr
fun)
                   , sc_dup :: DupFlag
sc_dup = DupFlag
NoDup, sc_cont :: SimplCont
sc_cont = SimplCont
cont }
simplExprF1 SimplEnv
env expr :: CoreExpr
expr@(Lam {}) SimplCont
cont
  = {-#SCC "simplExprF1-Lam" #-}
    SimplEnv
-> [OutId]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
env [OutId]
zapped_bndrs CoreExpr
body SimplCont
cont
        
        
        
        
        
        
  where
    ([OutId]
bndrs, CoreExpr
body) = CoreExpr -> ([OutId], CoreExpr)
forall b. Expr b -> ([b], Expr b)
collectBinders CoreExpr
expr
    zapped_bndrs :: [OutId]
zapped_bndrs = Int -> [OutId] -> [OutId]
zapLamBndrs Int
n_args [OutId]
bndrs
    n_args :: Int
n_args = SimplCont -> Int
countArgs SimplCont
cont
        
        
simplExprF1 SimplEnv
env (Case CoreExpr
scrut OutId
bndr Kind
_ [Alt OutId]
alts) SimplCont
cont
  = {-#SCC "simplExprF1-Case" #-}
    SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
scrut (Select { sc_dup :: DupFlag
sc_dup = DupFlag
NoDup, sc_bndr :: OutId
sc_bndr = OutId
bndr
                                 , sc_alts :: [Alt OutId]
sc_alts = [Alt OutId]
alts
                                 , sc_env :: SimplEnv
sc_env = SimplEnv
env, sc_cont :: SimplCont
sc_cont = SimplCont
cont })
simplExprF1 SimplEnv
env (Let (Rec [(OutId, CoreExpr)]
pairs) CoreExpr
body) SimplCont
cont
  | Just [(OutId, CoreExpr)]
pairs' <- [(OutId, CoreExpr)] -> Maybe [(OutId, CoreExpr)]
joinPointBindings_maybe [(OutId, CoreExpr)]
pairs
  = {-#SCC "simplRecJoinPoin" #-} SimplEnv
-> [(OutId, CoreExpr)]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplRecJoinPoint SimplEnv
env [(OutId, CoreExpr)]
pairs' CoreExpr
body SimplCont
cont
  | Bool
otherwise
  = {-#SCC "simplRecE" #-} SimplEnv
-> [(OutId, CoreExpr)]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplRecE SimplEnv
env [(OutId, CoreExpr)]
pairs CoreExpr
body SimplCont
cont
simplExprF1 SimplEnv
env (Let (NonRec OutId
bndr CoreExpr
rhs) CoreExpr
body) SimplCont
cont
  | Type Kind
ty <- CoreExpr
rhs    
  = {-#SCC "simplExprF1-NonRecLet-Type" #-}
    ASSERT( isTyVar bndr )
    do { Kind
ty' <- SimplEnv -> Kind -> SimplM Kind
simplType SimplEnv
env Kind
ty
       ; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF (SimplEnv -> OutId -> Kind -> SimplEnv
extendTvSubst SimplEnv
env OutId
bndr Kind
ty') CoreExpr
body SimplCont
cont }
  | Just (OutId
bndr', CoreExpr
rhs') <- OutId -> CoreExpr -> Maybe (OutId, CoreExpr)
joinPointBinding_maybe OutId
bndr CoreExpr
rhs
  = {-#SCC "simplNonRecJoinPoint" #-} SimplEnv
-> OutId
-> CoreExpr
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplNonRecJoinPoint SimplEnv
env OutId
bndr' CoreExpr
rhs' CoreExpr
body SimplCont
cont
  | Bool
otherwise
  = {-#SCC "simplNonRecE" #-} SimplEnv
-> OutId
-> (CoreExpr, SimplEnv)
-> ([OutId], CoreExpr)
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplNonRecE SimplEnv
env OutId
bndr (CoreExpr
rhs, SimplEnv
env) ([], CoreExpr
body) SimplCont
cont
simplJoinRhs :: SimplEnv -> InId -> InExpr -> SimplCont
             -> SimplM OutExpr
simplJoinRhs :: SimplEnv -> OutId -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplJoinRhs SimplEnv
env OutId
bndr CoreExpr
expr SimplCont
cont
  | Just Int
arity <- OutId -> Maybe Int
isJoinId_maybe OutId
bndr
  =  do { let ([OutId]
join_bndrs, CoreExpr
join_body) = Int -> CoreExpr -> ([OutId], CoreExpr)
forall b. Int -> Expr b -> ([b], Expr b)
collectNBinders Int
arity CoreExpr
expr
              mult :: Kind
mult = SimplCont -> Kind
contHoleScaling SimplCont
cont
        ; (SimplEnv
env', [OutId]
join_bndrs') <- SimplEnv -> [OutId] -> SimplM (SimplEnv, [OutId])
simplLamBndrs SimplEnv
env ((OutId -> OutId) -> [OutId] -> [OutId]
forall a b. (a -> b) -> [a] -> [b]
map (Kind -> OutId -> OutId
scaleVarBy Kind
mult) [OutId]
join_bndrs)
        ; CoreExpr
join_body' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
env' CoreExpr
join_body SimplCont
cont
        ; CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> SimplM CoreExpr) -> CoreExpr -> SimplM CoreExpr
forall a b. (a -> b) -> a -> b
$ [OutId] -> CoreExpr -> CoreExpr
forall b. [b] -> Expr b -> Expr b
mkLams [OutId]
join_bndrs' CoreExpr
join_body' }
  | Bool
otherwise
  = [Char] -> SDoc -> SimplM CoreExpr
forall a. HasCallStack => [Char] -> SDoc -> a
pprPanic [Char]
"simplJoinRhs" (OutId -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutId
bndr)
simplType :: SimplEnv -> InType -> SimplM OutType
        
        
simplType :: SimplEnv -> Kind -> SimplM Kind
simplType SimplEnv
env Kind
ty
  = 
    Kind -> ()
seqType Kind
new_ty () -> SimplM Kind -> SimplM Kind
`seq` Kind -> SimplM Kind
forall (m :: * -> *) a. Monad m => a -> m a
return Kind
new_ty
  where
    new_ty :: Kind
new_ty = SimplEnv -> Kind -> Kind
substTy SimplEnv
env Kind
ty
simplCoercionF :: SimplEnv -> InCoercion -> SimplCont
               -> SimplM (SimplFloats, OutExpr)
simplCoercionF :: SimplEnv -> Coercion -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplCoercionF SimplEnv
env Coercion
co SimplCont
cont
  = do { Coercion
co' <- SimplEnv -> Coercion -> SimplM Coercion
simplCoercion SimplEnv
env Coercion
co
       ; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (Coercion -> CoreExpr
forall b. Coercion -> Expr b
Coercion Coercion
co') SimplCont
cont }
simplCoercion :: SimplEnv -> InCoercion -> SimplM OutCoercion
simplCoercion :: SimplEnv -> Coercion -> SimplM Coercion
simplCoercion SimplEnv
env Coercion
co
  = do { OptCoercionOpts
opts <- SimplM OptCoercionOpts
getOptCoercionOpts
       ; let opt_co :: Coercion
opt_co = OptCoercionOpts -> TCvSubst -> Coercion -> Coercion
optCoercion OptCoercionOpts
opts (SimplEnv -> TCvSubst
getTCvSubst SimplEnv
env) Coercion
co
       ; Coercion -> ()
seqCo Coercion
opt_co () -> SimplM Coercion -> SimplM Coercion
`seq` Coercion -> SimplM Coercion
forall (m :: * -> *) a. Monad m => a -> m a
return Coercion
opt_co }
simplTick :: SimplEnv -> CoreTickish -> InExpr -> SimplCont
          -> SimplM (SimplFloats, OutExpr)
simplTick :: SimplEnv
-> CoreTickish
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplTick SimplEnv
env CoreTickish
tickish CoreExpr
expr SimplCont
cont
  
  
  
  
  
  
  
  
  
  
  
  | CoreTickish
tickish CoreTickish -> TickishScoping -> Bool
forall (pass :: TickishPass).
GenTickish pass -> TickishScoping -> Bool
`tickishScopesLike` TickishScoping
SoftScope
  = do { (SimplFloats
floats, CoreExpr
expr') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
expr SimplCont
cont
       ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, CoreTickish -> CoreExpr -> CoreExpr
mkTick CoreTickish
tickish CoreExpr
expr')
       }
  
  
  | Select {} <- SimplCont
cont, Just CoreExpr
expr' <- Maybe CoreExpr
push_tick_inside
  = SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
expr' SimplCont
cont
  
  
  
  
  
  | Bool
otherwise
  = SimplM (SimplFloats, CoreExpr)
no_floating_past_tick
 where
  
  push_tick_inside :: Maybe CoreExpr
push_tick_inside =
    case CoreExpr
expr0 of
      Case CoreExpr
scrut OutId
bndr Kind
ty [Alt OutId]
alts
             -> CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreExpr -> OutId -> Kind -> [Alt OutId] -> CoreExpr
forall b. Expr b -> b -> Kind -> [Alt b] -> Expr b
Case (CoreExpr -> CoreExpr
tickScrut CoreExpr
scrut) OutId
bndr Kind
ty ((Alt OutId -> Alt OutId) -> [Alt OutId] -> [Alt OutId]
forall a b. (a -> b) -> [a] -> [b]
map Alt OutId -> Alt OutId
tickAlt [Alt OutId]
alts)
      CoreExpr
_other -> Maybe CoreExpr
forall a. Maybe a
Nothing
   where ([CoreTickish]
ticks, CoreExpr
expr0) = (CoreTickish -> Bool) -> CoreExpr -> ([CoreTickish], CoreExpr)
forall b.
(CoreTickish -> Bool) -> Expr b -> ([CoreTickish], Expr b)
stripTicksTop CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
movable (CoreTickish -> CoreExpr -> CoreExpr
forall b. CoreTickish -> Expr b -> Expr b
Tick CoreTickish
tickish CoreExpr
expr)
         movable :: GenTickish pass -> Bool
movable GenTickish pass
t      = Bool -> Bool
not (GenTickish pass -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishCounts GenTickish pass
t) Bool -> Bool -> Bool
||
                          GenTickish pass
t GenTickish pass -> TickishScoping -> Bool
forall (pass :: TickishPass).
GenTickish pass -> TickishScoping -> Bool
`tickishScopesLike` TickishScoping
NoScope Bool -> Bool -> Bool
||
                          GenTickish pass -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishCanSplit GenTickish pass
t
         tickScrut :: CoreExpr -> CoreExpr
tickScrut CoreExpr
e    = (CoreTickish -> CoreExpr -> CoreExpr)
-> CoreExpr -> [CoreTickish] -> CoreExpr
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr CoreTickish -> CoreExpr -> CoreExpr
mkTick CoreExpr
e [CoreTickish]
ticks
         
         
         tickAlt :: Alt OutId -> Alt OutId
tickAlt (Alt AltCon
c [OutId]
bs CoreExpr
e) = AltCon -> [OutId] -> CoreExpr -> Alt OutId
forall b. AltCon -> [b] -> Expr b -> Alt b
Alt AltCon
c [OutId]
bs ((CoreTickish -> CoreExpr -> CoreExpr)
-> CoreExpr -> [CoreTickish] -> CoreExpr
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr CoreTickish -> CoreExpr -> CoreExpr
mkTick CoreExpr
e [CoreTickish]
ts_scope)
         ts_scope :: [CoreTickish]
ts_scope         = (CoreTickish -> CoreTickish) -> [CoreTickish] -> [CoreTickish]
forall a b. (a -> b) -> [a] -> [b]
map CoreTickish -> CoreTickish
forall (pass :: TickishPass). GenTickish pass -> GenTickish pass
mkNoCount ([CoreTickish] -> [CoreTickish]) -> [CoreTickish] -> [CoreTickish]
forall a b. (a -> b) -> a -> b
$
                            (CoreTickish -> Bool) -> [CoreTickish] -> [CoreTickish]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (CoreTickish -> Bool) -> CoreTickish -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CoreTickish -> TickishScoping -> Bool
forall (pass :: TickishPass).
GenTickish pass -> TickishScoping -> Bool
`tickishScopesLike` TickishScoping
NoScope)) [CoreTickish]
ticks
  no_floating_past_tick :: SimplM (SimplFloats, CoreExpr)
no_floating_past_tick =
    do { let (SimplCont
inc,SimplCont
outc) = SimplCont -> (SimplCont, SimplCont)
splitCont SimplCont
cont
       ; (SimplFloats
floats, CoreExpr
expr1) <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
expr SimplCont
inc
       ; let expr2 :: CoreExpr
expr2    = SimplFloats -> CoreExpr -> CoreExpr
wrapFloats SimplFloats
floats CoreExpr
expr1
             tickish' :: CoreTickish
tickish' = SimplEnv -> CoreTickish -> CoreTickish
forall {pass :: TickishPass}.
(XTickishId pass ~ OutId) =>
SimplEnv -> GenTickish pass -> GenTickish pass
simplTickish SimplEnv
env CoreTickish
tickish
       ; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (CoreTickish -> CoreExpr -> CoreExpr
mkTick CoreTickish
tickish' CoreExpr
expr2) SimplCont
outc
       }
  simplTickish :: SimplEnv -> GenTickish pass -> GenTickish pass
simplTickish SimplEnv
env GenTickish pass
tickish
    | Breakpoint XBreakpoint pass
ext Int
n [XTickishId pass]
ids <- GenTickish pass
tickish
          = XBreakpoint pass -> Int -> [XTickishId pass] -> GenTickish pass
forall (pass :: TickishPass).
XBreakpoint pass -> Int -> [XTickishId pass] -> GenTickish pass
Breakpoint XBreakpoint pass
ext Int
n ((OutId -> OutId) -> [OutId] -> [OutId]
forall a b. (a -> b) -> [a] -> [b]
map (SimplSR -> OutId
getDoneId (SimplSR -> OutId) -> (OutId -> SimplSR) -> OutId -> OutId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimplEnv -> OutId -> SimplSR
substId SimplEnv
env) [OutId]
[XTickishId pass]
ids)
    | Bool
otherwise = GenTickish pass
tickish
  
  splitCont :: SimplCont -> (SimplCont, SimplCont)
  splitCont :: SimplCont -> (SimplCont, SimplCont)
splitCont cont :: SimplCont
cont@(ApplyToTy { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
tail }) = (SimplCont
cont { sc_cont :: SimplCont
sc_cont = SimplCont
inc }, SimplCont
outc)
    where (SimplCont
inc,SimplCont
outc) = SimplCont -> (SimplCont, SimplCont)
splitCont SimplCont
tail
  splitCont (CastIt Coercion
co SimplCont
c) = (Coercion -> SimplCont -> SimplCont
CastIt Coercion
co SimplCont
inc, SimplCont
outc)
    where (SimplCont
inc,SimplCont
outc) = SimplCont -> (SimplCont, SimplCont)
splitCont SimplCont
c
  splitCont SimplCont
other = (Kind -> SimplCont
mkBoringStop (SimplCont -> Kind
contHoleType SimplCont
other), SimplCont
other)
  getDoneId :: SimplSR -> OutId
getDoneId (DoneId OutId
id)  = OutId
id
  getDoneId (DoneEx CoreExpr
e Maybe Int
_) = HasDebugCallStack => CoreExpr -> OutId
CoreExpr -> OutId
getIdFromTrivialExpr CoreExpr
e 
  getDoneId SimplSR
other = [Char] -> SDoc -> OutId
forall a. HasCallStack => [Char] -> SDoc -> a
pprPanic [Char]
"getDoneId" (SimplSR -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplSR
other)
rebuild :: SimplEnv -> OutExpr -> SimplCont -> SimplM (SimplFloats, OutExpr)
rebuild :: SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env CoreExpr
expr SimplCont
cont
  = case SimplCont
cont of
      Stop {}          -> (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, CoreExpr
expr)
      TickIt CoreTickish
t SimplCont
cont    -> SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (CoreTickish -> CoreExpr -> CoreExpr
mkTick CoreTickish
t CoreExpr
expr) SimplCont
cont
      CastIt Coercion
co SimplCont
cont   -> SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (CoreExpr -> Coercion -> CoreExpr
mkCast CoreExpr
expr Coercion
co) SimplCont
cont
                       
      Select { sc_bndr :: SimplCont -> OutId
sc_bndr = OutId
bndr, sc_alts :: SimplCont -> [Alt OutId]
sc_alts = [Alt OutId]
alts, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
se, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont }
        -> SimplEnv
-> CoreExpr
-> OutId
-> [Alt OutId]
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
rebuildCase (SimplEnv
se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env) CoreExpr
expr OutId
bndr [Alt OutId]
alts SimplCont
cont
      StrictArg { sc_fun :: SimplCont -> ArgInfo
sc_fun = ArgInfo
fun, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont, sc_fun_ty :: SimplCont -> Kind
sc_fun_ty = Kind
fun_ty }
        -> SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env (ArgInfo -> CoreExpr -> Kind -> ArgInfo
addValArgTo ArgInfo
fun CoreExpr
expr Kind
fun_ty ) SimplCont
cont
      StrictBind { sc_bndr :: SimplCont -> OutId
sc_bndr = OutId
b, sc_bndrs :: SimplCont -> [OutId]
sc_bndrs = [OutId]
bs, sc_body :: SimplCont -> CoreExpr
sc_body = CoreExpr
body
                 , sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
se, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont }
        -> do { (SimplFloats
floats1, SimplEnv
env') <- SimplEnv -> OutId -> CoreExpr -> SimplM (SimplFloats, SimplEnv)
simplNonRecX (SimplEnv
se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env) OutId
b CoreExpr
expr
                                  
                                  
              ; (SimplFloats
floats2, CoreExpr
expr') <- SimplEnv
-> [OutId]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
env' [OutId]
bs CoreExpr
body SimplCont
cont
              ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
expr') }
      ApplyToTy  { sc_arg_ty :: SimplCont -> Kind
sc_arg_ty = Kind
ty, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont}
        -> SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App CoreExpr
expr (Kind -> CoreExpr
forall b. Kind -> Expr b
Type Kind
ty)) SimplCont
cont
      ApplyToVal { sc_arg :: SimplCont -> CoreExpr
sc_arg = CoreExpr
arg, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
se, sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
dup_flag, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont}
        
        -> do { (DupFlag
_, SimplEnv
_, CoreExpr
arg') <- SimplEnv
-> DupFlag
-> SimplEnv
-> CoreExpr
-> SimplM (DupFlag, SimplEnv, CoreExpr)
simplArg SimplEnv
env DupFlag
dup_flag SimplEnv
se CoreExpr
arg
              ; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App CoreExpr
expr CoreExpr
arg') SimplCont
cont }
simplCast :: SimplEnv -> InExpr -> Coercion -> SimplCont
          -> SimplM (SimplFloats, OutExpr)
simplCast :: SimplEnv
-> CoreExpr
-> Coercion
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplCast SimplEnv
env CoreExpr
body Coercion
co0 SimplCont
cont0
  = do  { Coercion
co1   <- {-#SCC "simplCast-simplCoercion" #-} SimplEnv -> Coercion -> SimplM Coercion
simplCoercion SimplEnv
env Coercion
co0
        ; SimplCont
cont1 <- {-#SCC "simplCast-addCoerce" #-}
                   if Coercion -> Bool
isReflCo Coercion
co1
                   then SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return SimplCont
cont0  
                   else Coercion -> SimplCont -> SimplM SimplCont
addCoerce Coercion
co1 SimplCont
cont0
        ; {-#SCC "simplCast-simplExprF" #-} SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
body SimplCont
cont1 }
  where
        
        
        addCoerceM :: MOutCoercion -> SimplCont -> SimplM SimplCont
        addCoerceM :: MOutCoercion -> SimplCont -> SimplM SimplCont
addCoerceM MOutCoercion
MRefl   SimplCont
cont = SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return SimplCont
cont
        addCoerceM (MCo Coercion
co) SimplCont
cont = Coercion -> SimplCont -> SimplM SimplCont
addCoerce Coercion
co SimplCont
cont
        addCoerce :: OutCoercion -> SimplCont -> SimplM SimplCont
        addCoerce :: Coercion -> SimplCont -> SimplM SimplCont
addCoerce Coercion
co1 (CastIt Coercion
co2 SimplCont
cont)  
          | Coercion -> Bool
isReflexiveCo Coercion
co' = SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return SimplCont
cont
          | Bool
otherwise         = Coercion -> SimplCont -> SimplM SimplCont
addCoerce Coercion
co' SimplCont
cont
          where
            co' :: Coercion
co' = Coercion -> Coercion -> Coercion
mkTransCo Coercion
co1 Coercion
co2
        addCoerce Coercion
co (ApplyToTy { sc_arg_ty :: SimplCont -> Kind
sc_arg_ty = Kind
arg_ty, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
tail })
          | Just (Kind
arg_ty', MOutCoercion
m_co') <- Coercion -> Kind -> Maybe (Kind, MOutCoercion)
pushCoTyArg Coercion
co Kind
arg_ty
          = {-#SCC "addCoerce-pushCoTyArg" #-}
            do { SimplCont
tail' <- MOutCoercion -> SimplCont -> SimplM SimplCont
addCoerceM MOutCoercion
m_co' SimplCont
tail
               ; SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return (ApplyToTy { sc_arg_ty :: Kind
sc_arg_ty  = Kind
arg_ty'
                                   , sc_cont :: SimplCont
sc_cont    = SimplCont
tail'
                                   , sc_hole_ty :: Kind
sc_hole_ty = Coercion -> Kind
coercionLKind Coercion
co }) }
                                        
                                        
        
        
        
        
        addCoerce Coercion
co cont :: SimplCont
cont@(ApplyToVal { sc_arg :: SimplCont -> CoreExpr
sc_arg = CoreExpr
arg, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
arg_se
                                      , sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
dup, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
tail })
          | Just (MOutCoercion
m_co1, MOutCoercion
m_co2) <- Coercion -> Maybe (MOutCoercion, MOutCoercion)
pushCoValArg Coercion
co
          , MOutCoercion -> Bool
levity_ok MOutCoercion
m_co1
          = {-#SCC "addCoerce-pushCoValArg" #-}
            do { SimplCont
tail' <- MOutCoercion -> SimplCont -> SimplM SimplCont
addCoerceM MOutCoercion
m_co2 SimplCont
tail
               ; case MOutCoercion
m_co1 of {
                   MOutCoercion
MRefl -> SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplCont
cont { sc_cont :: SimplCont
sc_cont = SimplCont
tail'
                                         , sc_hole_ty :: Kind
sc_hole_ty = Coercion -> Kind
coercionLKind Coercion
co }) ;
                      
                      
                   MCo Coercion
co1 ->
            do { (DupFlag
dup', SimplEnv
arg_se', CoreExpr
arg') <- SimplEnv
-> DupFlag
-> SimplEnv
-> CoreExpr
-> SimplM (DupFlag, SimplEnv, CoreExpr)
simplArg SimplEnv
env DupFlag
dup SimplEnv
arg_se CoreExpr
arg
                    
                    
                    
                    
                    
               ; SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return (ApplyToVal { sc_arg :: CoreExpr
sc_arg  = CoreExpr -> Coercion -> CoreExpr
mkCast CoreExpr
arg' Coercion
co1
                                    , sc_env :: SimplEnv
sc_env  = SimplEnv
arg_se'
                                    , sc_dup :: DupFlag
sc_dup  = DupFlag
dup'
                                    , sc_cont :: SimplCont
sc_cont = SimplCont
tail'
                                    , sc_hole_ty :: Kind
sc_hole_ty = Coercion -> Kind
coercionLKind Coercion
co }) } } }
        addCoerce Coercion
co SimplCont
cont
          | Coercion -> Bool
isReflexiveCo Coercion
co = SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return SimplCont
cont  
                                            
                                            
          | Bool
otherwise        = SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion -> SimplCont -> SimplCont
CastIt Coercion
co SimplCont
cont)
        levity_ok :: MCoercionR -> Bool
        levity_ok :: MOutCoercion -> Bool
levity_ok MOutCoercion
MRefl = Bool
True
        levity_ok (MCo Coercion
co) = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Kind -> Bool
isTypeLevPoly (Kind -> Bool) -> Kind -> Bool
forall a b. (a -> b) -> a -> b
$ Coercion -> Kind
coercionRKind Coercion
co
          
          
          
simplArg :: SimplEnv -> DupFlag -> StaticEnv -> CoreExpr
         -> SimplM (DupFlag, StaticEnv, OutExpr)
simplArg :: SimplEnv
-> DupFlag
-> SimplEnv
-> CoreExpr
-> SimplM (DupFlag, SimplEnv, CoreExpr)
simplArg SimplEnv
env DupFlag
dup_flag SimplEnv
arg_env CoreExpr
arg
  | DupFlag -> Bool
isSimplified DupFlag
dup_flag
  = (DupFlag, SimplEnv, CoreExpr)
-> SimplM (DupFlag, SimplEnv, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (DupFlag
dup_flag, SimplEnv
arg_env, CoreExpr
arg)
  | Bool
otherwise
  = do { let arg_env' :: SimplEnv
arg_env' = SimplEnv
arg_env SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env
       ; CoreExpr
arg' <- SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr SimplEnv
arg_env'  CoreExpr
arg
       ; (DupFlag, SimplEnv, CoreExpr)
-> SimplM (DupFlag, SimplEnv, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (DupFlag
Simplified, SimplEnv -> SimplEnv
zapSubstEnv SimplEnv
arg_env', CoreExpr
arg') }
         
         
simplLam :: SimplEnv -> [InId] -> InExpr -> SimplCont
         -> SimplM (SimplFloats, OutExpr)
simplLam :: SimplEnv
-> [OutId]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
env [] CoreExpr
body SimplCont
cont
  = SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
body SimplCont
cont
simplLam SimplEnv
env (OutId
bndr:[OutId]
bndrs) CoreExpr
body (ApplyToTy { sc_arg_ty :: SimplCont -> Kind
sc_arg_ty = Kind
arg_ty, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont })
  = do { Tick -> SimplM ()
tick (OutId -> Tick
BetaReduction OutId
bndr)
       ; SimplEnv
-> [OutId]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplLam (SimplEnv -> OutId -> Kind -> SimplEnv
extendTvSubst SimplEnv
env OutId
bndr Kind
arg_ty) [OutId]
bndrs CoreExpr
body SimplCont
cont }
simplLam SimplEnv
env (OutId
bndr:[OutId]
bndrs) CoreExpr
body (ApplyToVal { sc_arg :: SimplCont -> CoreExpr
sc_arg = CoreExpr
arg, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
arg_se
                                           , sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont, sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
dup })
  | DupFlag -> Bool
isSimplified DupFlag
dup  
                      
  = do  { Tick -> SimplM ()
tick (OutId -> Tick
BetaReduction OutId
bndr)
        ; (SimplFloats
floats1, SimplEnv
env') <- SimplEnv -> OutId -> CoreExpr -> SimplM (SimplFloats, SimplEnv)
simplNonRecX SimplEnv
env OutId
zapped_bndr CoreExpr
arg
        ; (SimplFloats
floats2, CoreExpr
expr') <- SimplEnv
-> [OutId]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
env' [OutId]
bndrs CoreExpr
body SimplCont
cont
        ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
expr') }
  | Bool
otherwise
  = do  { Tick -> SimplM ()
tick (OutId -> Tick
BetaReduction OutId
bndr)
        ; SimplEnv
-> OutId
-> (CoreExpr, SimplEnv)
-> ([OutId], CoreExpr)
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplNonRecE SimplEnv
env OutId
zapped_bndr (CoreExpr
arg, SimplEnv
arg_se) ([OutId]
bndrs, CoreExpr
body) SimplCont
cont }
  where
    zapped_bndr :: OutId
zapped_bndr  
      | OutId -> Bool
isId OutId
bndr = OutId -> OutId
zapStableUnfolding OutId
bndr
      | Bool
otherwise = OutId
bndr
      
      
      
      
simplLam SimplEnv
env [OutId]
bndrs CoreExpr
body (TickIt CoreTickish
tickish SimplCont
cont)
  | Bool -> Bool
not (CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishCounts CoreTickish
tickish)
  = SimplEnv
-> [OutId]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
env [OutId]
bndrs CoreExpr
body SimplCont
cont
        
simplLam SimplEnv
env [OutId]
bndrs CoreExpr
body SimplCont
cont
  = do  { (SimplEnv
env', [OutId]
bndrs') <- SimplEnv -> [OutId] -> SimplM (SimplEnv, [OutId])
simplLamBndrs SimplEnv
env [OutId]
bndrs
        ; CoreExpr
body' <- SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr SimplEnv
env' CoreExpr
body
        ; CoreExpr
new_lam <- SimplEnv -> [OutId] -> CoreExpr -> SimplCont -> SimplM CoreExpr
mkLam SimplEnv
env [OutId]
bndrs' CoreExpr
body' SimplCont
cont
        ; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env' CoreExpr
new_lam SimplCont
cont }
simplLamBndr :: SimplEnv -> InBndr -> SimplM (SimplEnv, OutBndr)
simplLamBndr :: SimplEnv -> OutId -> SimplM (SimplEnv, OutId)
simplLamBndr SimplEnv
env OutId
bndr
  | OutId -> Bool
isId OutId
bndr Bool -> Bool -> Bool
&& Unfolding -> Bool
hasCoreUnfolding Unfolding
old_unf   
  = do { (SimplEnv
env1, OutId
bndr1) <- SimplEnv -> OutId -> SimplM (SimplEnv, OutId)
simplBinder SimplEnv
env OutId
bndr
       ; Unfolding
unf'          <- SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> OutId
-> Kind
-> ArityType
-> Unfolding
-> SimplM Unfolding
simplStableUnfolding SimplEnv
env1 TopLevelFlag
NotTopLevel MaybeJoinCont
forall a. Maybe a
Nothing OutId
bndr
                                      (OutId -> Kind
idType OutId
bndr1) (OutId -> ArityType
idArityType OutId
bndr1) Unfolding
old_unf
       ; let bndr2 :: OutId
bndr2 = OutId
bndr1 OutId -> Unfolding -> OutId
`setIdUnfolding` Unfolding
unf'
       ; (SimplEnv, OutId) -> SimplM (SimplEnv, OutId)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> OutId -> SimplEnv
modifyInScope SimplEnv
env1 OutId
bndr2, OutId
bndr2) }
  | Bool
otherwise
  = SimplEnv -> OutId -> SimplM (SimplEnv, OutId)
simplBinder SimplEnv
env OutId
bndr                
  where
    old_unf :: Unfolding
old_unf = OutId -> Unfolding
idUnfolding OutId
bndr
simplLamBndrs :: SimplEnv -> [InBndr] -> SimplM (SimplEnv, [OutBndr])
simplLamBndrs :: SimplEnv -> [OutId] -> SimplM (SimplEnv, [OutId])
simplLamBndrs SimplEnv
env [OutId]
bndrs = (SimplEnv -> OutId -> SimplM (SimplEnv, OutId))
-> SimplEnv -> [OutId] -> SimplM (SimplEnv, [OutId])
forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM SimplEnv -> OutId -> SimplM (SimplEnv, OutId)
simplLamBndr SimplEnv
env [OutId]
bndrs
simplNonRecE :: SimplEnv
             -> InId                    
                                        
             -> (InExpr, SimplEnv)      
             -> ([InBndr], InExpr)      
                                        
             -> SimplCont
             -> SimplM (SimplFloats, OutExpr)
simplNonRecE :: SimplEnv
-> OutId
-> (CoreExpr, SimplEnv)
-> ([OutId], CoreExpr)
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplNonRecE SimplEnv
env OutId
bndr (CoreExpr
rhs, SimplEnv
rhs_se) ([OutId]
bndrs, CoreExpr
body) SimplCont
cont
  | ASSERT( isId bndr && not (isJoinId bndr) ) True
  , Just SimplEnv
env' <- SimplEnv
-> TopLevelFlag -> OutId -> CoreExpr -> SimplEnv -> Maybe SimplEnv
preInlineUnconditionally SimplEnv
env TopLevelFlag
NotTopLevel OutId
bndr CoreExpr
rhs SimplEnv
rhs_se
  = do { Tick -> SimplM ()
tick (OutId -> Tick
PreInlineUnconditionally OutId
bndr)
       ; 
         SimplEnv
-> [OutId]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
env' [OutId]
bndrs CoreExpr
body SimplCont
cont }
  | Bool
otherwise
  = do { (SimplEnv
env1, OutId
bndr1) <- SimplEnv -> OutId -> SimplM (SimplEnv, OutId)
simplNonRecBndr SimplEnv
env OutId
bndr
       
       
       ; if OutId -> Bool
isStrictId OutId
bndr1 Bool -> Bool -> Bool
&& SimplMode -> Bool
sm_case_case (SimplEnv -> SimplMode
getMode SimplEnv
env)
         then SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF (SimplEnv
rhs_se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env) CoreExpr
rhs
                   (StrictBind { sc_bndr :: OutId
sc_bndr = OutId
bndr, sc_bndrs :: [OutId]
sc_bndrs = [OutId]
bndrs, sc_body :: CoreExpr
sc_body = CoreExpr
body
                               , sc_env :: SimplEnv
sc_env = SimplEnv
env, sc_cont :: SimplCont
sc_cont = SimplCont
cont, sc_dup :: DupFlag
sc_dup = DupFlag
NoDup })
       
         else do
       { (SimplEnv
env2, OutId
bndr2) <- SimplEnv
-> OutId -> OutId -> MaybeJoinCont -> SimplM (SimplEnv, OutId)
addBndrRules SimplEnv
env1 OutId
bndr OutId
bndr1 MaybeJoinCont
forall a. Maybe a
Nothing
       ; (SimplFloats
floats1, SimplEnv
env3) <- SimplEnv
-> TopLevelFlag
-> RecFlag
-> OutId
-> OutId
-> CoreExpr
-> SimplEnv
-> SimplM (SimplFloats, SimplEnv)
simplLazyBind SimplEnv
env2 TopLevelFlag
NotTopLevel RecFlag
NonRecursive OutId
bndr OutId
bndr2 CoreExpr
rhs SimplEnv
rhs_se
       ; (SimplFloats
floats2, CoreExpr
expr') <- SimplEnv
-> [OutId]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
env3 [OutId]
bndrs CoreExpr
body SimplCont
cont
       ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
expr') } }
simplRecE :: SimplEnv
          -> [(InId, InExpr)]
          -> InExpr
          -> SimplCont
          -> SimplM (SimplFloats, OutExpr)
simplRecE :: SimplEnv
-> [(OutId, CoreExpr)]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplRecE SimplEnv
env [(OutId, CoreExpr)]
pairs CoreExpr
body SimplCont
cont
  = do  { let bndrs :: [OutId]
bndrs = ((OutId, CoreExpr) -> OutId) -> [(OutId, CoreExpr)] -> [OutId]
forall a b. (a -> b) -> [a] -> [b]
map (OutId, CoreExpr) -> OutId
forall a b. (a, b) -> a
fst [(OutId, CoreExpr)]
pairs
        ; MASSERT(all (not . isJoinId) bndrs)
        ; SimplEnv
env1 <- SimplEnv -> [OutId] -> SimplM SimplEnv
simplRecBndrs SimplEnv
env [OutId]
bndrs
                
                
        ; (SimplFloats
floats1, SimplEnv
env2) <- SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> [(OutId, CoreExpr)]
-> SimplM (SimplFloats, SimplEnv)
simplRecBind SimplEnv
env1 TopLevelFlag
NotTopLevel MaybeJoinCont
forall a. Maybe a
Nothing [(OutId, CoreExpr)]
pairs
        ; (SimplFloats
floats2, CoreExpr
expr') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env2 CoreExpr
body SimplCont
cont
        ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
expr') }
type MaybeJoinCont = Maybe SimplCont
  
  
  
simplNonRecJoinPoint :: SimplEnv -> InId -> InExpr
                     -> InExpr -> SimplCont
                     -> SimplM (SimplFloats, OutExpr)
simplNonRecJoinPoint :: SimplEnv
-> OutId
-> CoreExpr
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplNonRecJoinPoint SimplEnv
env OutId
bndr CoreExpr
rhs CoreExpr
body SimplCont
cont
  | ASSERT( isJoinId bndr ) True
  , Just SimplEnv
env' <- SimplEnv
-> TopLevelFlag -> OutId -> CoreExpr -> SimplEnv -> Maybe SimplEnv
preInlineUnconditionally SimplEnv
env TopLevelFlag
NotTopLevel OutId
bndr CoreExpr
rhs SimplEnv
env
  = do { Tick -> SimplM ()
tick (OutId -> Tick
PreInlineUnconditionally OutId
bndr)
       ; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env' CoreExpr
body SimplCont
cont }
   | Bool
otherwise
   = SimplEnv
-> SimplCont
-> (SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplM (SimplFloats, CoreExpr)
wrapJoinCont SimplEnv
env SimplCont
cont ((SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr))
 -> SimplM (SimplFloats, CoreExpr))
-> (SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplM (SimplFloats, CoreExpr)
forall a b. (a -> b) -> a -> b
$ \ SimplEnv
env SimplCont
cont ->
     do { 
          
        ; let mult :: Kind
mult   = SimplCont -> Kind
contHoleScaling SimplCont
cont
              res_ty :: Kind
res_ty = SimplCont -> Kind
contResultType SimplCont
cont
        ; (SimplEnv
env1, OutId
bndr1)    <- SimplEnv -> OutId -> Kind -> Kind -> SimplM (SimplEnv, OutId)
simplNonRecJoinBndr SimplEnv
env OutId
bndr Kind
mult Kind
res_ty
        ; (SimplEnv
env2, OutId
bndr2)    <- SimplEnv
-> OutId -> OutId -> MaybeJoinCont -> SimplM (SimplEnv, OutId)
addBndrRules SimplEnv
env1 OutId
bndr OutId
bndr1 (SimplCont -> MaybeJoinCont
forall a. a -> Maybe a
Just SimplCont
cont)
        ; (SimplFloats
floats1, SimplEnv
env3)  <- SimplEnv
-> SimplCont
-> OutId
-> OutId
-> CoreExpr
-> SimplEnv
-> SimplM (SimplFloats, SimplEnv)
simplJoinBind SimplEnv
env2 SimplCont
cont OutId
bndr OutId
bndr2 CoreExpr
rhs SimplEnv
env
        ; (SimplFloats
floats2, CoreExpr
body') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env3 CoreExpr
body SimplCont
cont
        ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
body') }
simplRecJoinPoint :: SimplEnv -> [(InId, InExpr)]
                  -> InExpr -> SimplCont
                  -> SimplM (SimplFloats, OutExpr)
simplRecJoinPoint :: SimplEnv
-> [(OutId, CoreExpr)]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplRecJoinPoint SimplEnv
env [(OutId, CoreExpr)]
pairs CoreExpr
body SimplCont
cont
  = SimplEnv
-> SimplCont
-> (SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplM (SimplFloats, CoreExpr)
wrapJoinCont SimplEnv
env SimplCont
cont ((SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr))
 -> SimplM (SimplFloats, CoreExpr))
-> (SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplM (SimplFloats, CoreExpr)
forall a b. (a -> b) -> a -> b
$ \ SimplEnv
env SimplCont
cont ->
    do { let bndrs :: [OutId]
bndrs  = ((OutId, CoreExpr) -> OutId) -> [(OutId, CoreExpr)] -> [OutId]
forall a b. (a -> b) -> [a] -> [b]
map (OutId, CoreExpr) -> OutId
forall a b. (a, b) -> a
fst [(OutId, CoreExpr)]
pairs
             mult :: Kind
mult   = SimplCont -> Kind
contHoleScaling SimplCont
cont
             res_ty :: Kind
res_ty = SimplCont -> Kind
contResultType SimplCont
cont
       ; SimplEnv
env1 <- SimplEnv -> [OutId] -> Kind -> Kind -> SimplM SimplEnv
simplRecJoinBndrs SimplEnv
env [OutId]
bndrs Kind
mult Kind
res_ty
               
               
       ; (SimplFloats
floats1, SimplEnv
env2)  <- SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> [(OutId, CoreExpr)]
-> SimplM (SimplFloats, SimplEnv)
simplRecBind SimplEnv
env1 TopLevelFlag
NotTopLevel (SimplCont -> MaybeJoinCont
forall a. a -> Maybe a
Just SimplCont
cont) [(OutId, CoreExpr)]
pairs
       ; (SimplFloats
floats2, CoreExpr
body') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env2 CoreExpr
body SimplCont
cont
       ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
body') }
wrapJoinCont :: SimplEnv -> SimplCont
             -> (SimplEnv -> SimplCont -> SimplM (SimplFloats, OutExpr))
             -> SimplM (SimplFloats, OutExpr)
wrapJoinCont :: SimplEnv
-> SimplCont
-> (SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplM (SimplFloats, CoreExpr)
wrapJoinCont SimplEnv
env SimplCont
cont SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr)
thing_inside
  | SimplCont -> Bool
contIsStop SimplCont
cont        
  = SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr)
thing_inside SimplEnv
env SimplCont
cont
  | Bool -> Bool
not (SimplMode -> Bool
sm_case_case (SimplEnv -> SimplMode
getMode SimplEnv
env))
    
  = do { (SimplFloats
floats1, CoreExpr
expr1) <- SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr)
thing_inside SimplEnv
env (Kind -> SimplCont
mkBoringStop (SimplCont -> Kind
contHoleType SimplCont
cont))
       ; let (SimplFloats
floats2, CoreExpr
expr2) = SimplFloats -> CoreExpr -> (SimplFloats, CoreExpr)
wrapJoinFloatsX SimplFloats
floats1 CoreExpr
expr1
       ; (SimplFloats
floats3, CoreExpr
expr3) <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild (SimplEnv
env SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
floats2) CoreExpr
expr2 SimplCont
cont
       ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats2 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats3, CoreExpr
expr3) }
  | Bool
otherwise
    
  = do { (SimplFloats
floats1, SimplCont
cont')  <- SimplEnv -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableCont SimplEnv
env SimplCont
cont
       ; (SimplFloats
floats2, CoreExpr
result) <- SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr)
thing_inside (SimplEnv
env SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
floats1) SimplCont
cont'
       ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
result) }
trimJoinCont :: Id -> Maybe JoinArity -> SimplCont -> SimplCont
trimJoinCont :: OutId -> Maybe Int -> SimplCont -> SimplCont
trimJoinCont OutId
_ Maybe Int
Nothing SimplCont
cont
  = SimplCont
cont 
trimJoinCont OutId
var (Just Int
arity) SimplCont
cont
  = Int -> SimplCont -> SimplCont
trim Int
arity SimplCont
cont
  where
    trim :: Int -> SimplCont -> SimplCont
trim Int
0 cont :: SimplCont
cont@(Stop {})
      = SimplCont
cont
    trim Int
0 SimplCont
cont
      = Kind -> SimplCont
mkBoringStop (SimplCont -> Kind
contResultType SimplCont
cont)
    trim Int
n cont :: SimplCont
cont@(ApplyToVal { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k })
      = SimplCont
cont { sc_cont :: SimplCont
sc_cont = Int -> SimplCont -> SimplCont
trim (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) SimplCont
k }
    trim Int
n cont :: SimplCont
cont@(ApplyToTy { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k })
      = SimplCont
cont { sc_cont :: SimplCont
sc_cont = Int -> SimplCont -> SimplCont
trim (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) SimplCont
k } 
    trim Int
_ SimplCont
cont
      = [Char] -> SDoc -> SimplCont
forall a. HasCallStack => [Char] -> SDoc -> a
pprPanic [Char]
"completeCall" (SDoc -> SimplCont) -> SDoc -> SimplCont
forall a b. (a -> b) -> a -> b
$ OutId -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutId
var SDoc -> SDoc -> SDoc
$$ SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
cont
simplVar :: SimplEnv -> InVar -> SimplM OutExpr
simplVar :: SimplEnv -> OutId -> SimplM CoreExpr
simplVar SimplEnv
env OutId
var
  
  | OutId -> Bool
isTyVar OutId
var = CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> SimplM CoreExpr) -> CoreExpr -> SimplM CoreExpr
forall a b. (a -> b) -> a -> b
$! Kind -> CoreExpr
forall b. Kind -> Expr b
Type (Kind -> CoreExpr) -> Kind -> CoreExpr
forall a b. (a -> b) -> a -> b
$! (SimplEnv -> OutId -> Kind
substTyVar SimplEnv
env OutId
var)
  | OutId -> Bool
isCoVar OutId
var = CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> SimplM CoreExpr) -> CoreExpr -> SimplM CoreExpr
forall a b. (a -> b) -> a -> b
$! Coercion -> CoreExpr
forall b. Coercion -> Expr b
Coercion (Coercion -> CoreExpr) -> Coercion -> CoreExpr
forall a b. (a -> b) -> a -> b
$! (SimplEnv -> OutId -> Coercion
substCoVar SimplEnv
env OutId
var)
  | Bool
otherwise
  = case SimplEnv -> OutId -> SimplSR
substId SimplEnv
env OutId
var of
        ContEx TvSubstEnv
tvs CvSubstEnv
cvs SimplIdSubst
ids CoreExpr
e -> let env' :: SimplEnv
env' = SimplEnv -> TvSubstEnv -> CvSubstEnv -> SimplIdSubst -> SimplEnv
setSubstEnv SimplEnv
env TvSubstEnv
tvs CvSubstEnv
cvs SimplIdSubst
ids
                                in SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr SimplEnv
env' CoreExpr
e
        DoneId OutId
var1          -> CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (OutId -> CoreExpr
forall b. OutId -> Expr b
Var OutId
var1)
        DoneEx CoreExpr
e Maybe Int
_           -> CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
e
simplIdF :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr)
simplIdF :: SimplEnv -> OutId -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplIdF SimplEnv
env OutId
var SimplCont
cont
  = case SimplEnv -> OutId -> SimplSR
substId SimplEnv
env OutId
var of
      ContEx TvSubstEnv
tvs CvSubstEnv
cvs SimplIdSubst
ids CoreExpr
e ->
          let env' :: SimplEnv
env' = SimplEnv -> TvSubstEnv -> CvSubstEnv -> SimplIdSubst -> SimplEnv
setSubstEnv SimplEnv
env TvSubstEnv
tvs CvSubstEnv
cvs SimplIdSubst
ids
          in SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env' CoreExpr
e SimplCont
cont
          
          
      DoneId OutId
var1 ->
          let cont' :: SimplCont
cont' = OutId -> Maybe Int -> SimplCont -> SimplCont
trimJoinCont OutId
var (OutId -> Maybe Int
isJoinId_maybe OutId
var1) SimplCont
cont
          in SimplEnv -> OutId -> SimplCont -> SimplM (SimplFloats, CoreExpr)
completeCall SimplEnv
env OutId
var1 SimplCont
cont'
      DoneEx CoreExpr
e Maybe Int
mb_join ->
          let env' :: SimplEnv
env' = SimplEnv -> SimplEnv
zapSubstEnv SimplEnv
env
              cont' :: SimplCont
cont' = OutId -> Maybe Int -> SimplCont -> SimplCont
trimJoinCont OutId
var Maybe Int
mb_join SimplCont
cont
          in SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env' CoreExpr
e SimplCont
cont'
              
              
              
              
              
              
              
              
              
completeCall :: SimplEnv -> OutId -> SimplCont -> SimplM (SimplFloats, OutExpr)
completeCall :: SimplEnv -> OutId -> SimplCont -> SimplM (SimplFloats, CoreExpr)
completeCall SimplEnv
env OutId
var SimplCont
cont
  | Just CoreExpr
expr <- Logger
-> DynFlags
-> Int
-> OutId
-> Bool
-> Bool
-> [ArgSummary]
-> CallCtxt
-> Maybe CoreExpr
callSiteInline Logger
logger DynFlags
dflags Int
case_depth OutId
var Bool
active_unf
                                Bool
lone_variable [ArgSummary]
arg_infos CallCtxt
interesting_cont
  
  = do { Tick -> SimplM ()
checkedTick (OutId -> Tick
UnfoldingDone OutId
var)
       ; CoreExpr -> SimplCont -> SimplM ()
dump_inline CoreExpr
expr SimplCont
cont
       ; let env1 :: SimplEnv
env1 = SimplEnv -> SimplEnv
zapSubstEnv SimplEnv
env
       ; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env1 CoreExpr
expr SimplCont
cont }
  | Bool
otherwise
  
  = do { RuleEnv
rule_base <- SimplM RuleEnv
getSimplRules
       ; let rules :: [CoreRule]
rules = RuleEnv -> OutId -> [CoreRule]
getRules RuleEnv
rule_base OutId
var
             info :: ArgInfo
info = SimplEnv -> OutId -> [CoreRule] -> Int -> SimplCont -> ArgInfo
mkArgInfo SimplEnv
env OutId
var [CoreRule]
rules
                              Int
n_val_args SimplCont
call_cont
       ; SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env ArgInfo
info SimplCont
cont }
  where
    dflags :: DynFlags
dflags     = SimplEnv -> DynFlags
seDynFlags SimplEnv
env
    case_depth :: Int
case_depth = SimplEnv -> Int
seCaseDepth SimplEnv
env
    logger :: Logger
logger     = SimplEnv -> Logger
seLogger SimplEnv
env
    (Bool
lone_variable, [ArgSummary]
arg_infos, SimplCont
call_cont) = SimplCont -> (Bool, [ArgSummary], SimplCont)
contArgs SimplCont
cont
    n_val_args :: Int
n_val_args       = [ArgSummary] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ArgSummary]
arg_infos
    interesting_cont :: CallCtxt
interesting_cont = SimplEnv -> SimplCont -> CallCtxt
interestingCallContext SimplEnv
env SimplCont
call_cont
    active_unf :: Bool
active_unf       = SimplMode -> OutId -> Bool
activeUnfolding (SimplEnv -> SimplMode
getMode SimplEnv
env) OutId
var
    log_inlining :: SDoc -> SimplM ()
log_inlining SDoc
doc
      = IO () -> SimplM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> SimplM ()) -> IO () -> SimplM ()
forall a b. (a -> b) -> a -> b
$ Logger -> DumpAction
putDumpMsg Logger
logger DynFlags
dflags
           (PrintUnqualified -> PprStyle
mkDumpStyle PrintUnqualified
alwaysQualify)
           DumpFlag
Opt_D_dump_inlinings
           [Char]
"" DumpFormat
FormatText SDoc
doc
    dump_inline :: CoreExpr -> SimplCont -> SimplM ()
dump_inline CoreExpr
unfolding SimplCont
cont
      | Bool -> Bool
not (DumpFlag -> DynFlags -> Bool
dopt DumpFlag
Opt_D_dump_inlinings DynFlags
dflags) = () -> SimplM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      | Bool -> Bool
not (DumpFlag -> DynFlags -> Bool
dopt DumpFlag
Opt_D_verbose_core2core DynFlags
dflags)
      = Bool -> SimplM () -> SimplM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Name -> Bool
isExternalName (OutId -> Name
idName OutId
var)) (SimplM () -> SimplM ()) -> SimplM () -> SimplM ()
forall a b. (a -> b) -> a -> b
$
            SDoc -> SimplM ()
log_inlining (SDoc -> SimplM ()) -> SDoc -> SimplM ()
forall a b. (a -> b) -> a -> b
$
                [SDoc] -> SDoc
sep [[Char] -> SDoc
text [Char]
"Inlining done:", Int -> SDoc -> SDoc
nest Int
4 (OutId -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutId
var)]
      | Bool
otherwise
      = SDoc -> SimplM ()
log_inlining (SDoc -> SimplM ()) -> SDoc -> SimplM ()
forall a b. (a -> b) -> a -> b
$
           [SDoc] -> SDoc
sep [[Char] -> SDoc
text [Char]
"Inlining done: " SDoc -> SDoc -> SDoc
<> OutId -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutId
var,
                Int -> SDoc -> SDoc
nest Int
4 ([SDoc] -> SDoc
vcat [[Char] -> SDoc
text [Char]
"Inlined fn: " SDoc -> SDoc -> SDoc
<+> Int -> SDoc -> SDoc
nest Int
2 (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
unfolding),
                              [Char] -> SDoc
text [Char]
"Cont:  " SDoc -> SDoc -> SDoc
<+> SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
cont])]
rebuildCall :: SimplEnv
            -> ArgInfo
            -> SimplCont
            -> SimplM (SimplFloats, OutExpr)
rebuildCall :: SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env (ArgInfo { ai_fun :: ArgInfo -> OutId
ai_fun = OutId
fun, ai_args :: ArgInfo -> [ArgSpec]
ai_args = [ArgSpec]
rev_args, ai_dmds :: ArgInfo -> [Demand]
ai_dmds = [] }) SimplCont
cont
  
  
  
  
  
  
  
  
  
  
  | Bool -> Bool
not (SimplCont -> Bool
contIsTrivial SimplCont
cont)     
                                 
                                 
  = Kind -> ()
seqType Kind
cont_ty ()
-> SimplM (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
`seq`        
    (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, CoreExpr -> Kind -> CoreExpr
castBottomExpr CoreExpr
res Kind
cont_ty)
  where
    res :: CoreExpr
res     = OutId -> [ArgSpec] -> CoreExpr
argInfoExpr OutId
fun [ArgSpec]
rev_args
    cont_ty :: Kind
cont_ty = SimplCont -> Kind
contResultType SimplCont
cont
rebuildCall SimplEnv
env info :: ArgInfo
info@(ArgInfo { ai_fun :: ArgInfo -> OutId
ai_fun = OutId
fun, ai_args :: ArgInfo -> [ArgSpec]
ai_args = [ArgSpec]
rev_args
                              , ai_rules :: ArgInfo -> FunRules
ai_rules = Just (Int
nr_wanted, [CoreRule]
rules) }) SimplCont
cont
  | Int
nr_wanted Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
|| Bool
no_more_args
  , let info' :: ArgInfo
info' = ArgInfo
info { ai_rules :: FunRules
ai_rules = FunRules
forall a. Maybe a
Nothing }
  = 
    
    
    do { Maybe (SimplEnv, CoreExpr, SimplCont)
mb_match <- SimplEnv
-> [CoreRule]
-> OutId
-> [ArgSpec]
-> SimplCont
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
tryRules SimplEnv
env [CoreRule]
rules OutId
fun ([ArgSpec] -> [ArgSpec]
forall a. [a] -> [a]
reverse [ArgSpec]
rev_args) SimplCont
cont
       ; case Maybe (SimplEnv, CoreExpr, SimplCont)
mb_match of
             Just (SimplEnv
env', CoreExpr
rhs, SimplCont
cont') -> SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env' CoreExpr
rhs SimplCont
cont'
             Maybe (SimplEnv, CoreExpr, SimplCont)
Nothing                 -> SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env ArgInfo
info' SimplCont
cont }
  where
    no_more_args :: Bool
no_more_args = case SimplCont
cont of
                      ApplyToTy  {} -> Bool
False
                      ApplyToVal {} -> Bool
False
                      SimplCont
_             -> Bool
True
rebuildCall SimplEnv
env ArgInfo
info (CastIt Coercion
co SimplCont
cont)
  = SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env (ArgInfo -> Coercion -> ArgInfo
addCastTo ArgInfo
info Coercion
co) SimplCont
cont
rebuildCall SimplEnv
env ArgInfo
info (ApplyToTy { sc_arg_ty :: SimplCont -> Kind
sc_arg_ty = Kind
arg_ty, sc_hole_ty :: SimplCont -> Kind
sc_hole_ty = Kind
hole_ty, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont })
  = SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env (ArgInfo -> Kind -> Kind -> ArgInfo
addTyArgTo ArgInfo
info Kind
arg_ty Kind
hole_ty) SimplCont
cont
rebuildCall SimplEnv
env (ArgInfo { ai_fun :: ArgInfo -> OutId
ai_fun = OutId
fun_id, ai_args :: ArgInfo -> [ArgSpec]
ai_args = [ArgSpec]
rev_args })
            (ApplyToVal { sc_arg :: SimplCont -> CoreExpr
sc_arg = CoreExpr
arg, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
arg_se
                        , sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont, sc_hole_ty :: SimplCont -> Kind
sc_hole_ty = Kind
fun_ty })
  | OutId
fun_id OutId -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
runRWKey
  , Bool -> Bool
not (SimplCont -> Bool
contIsStop SimplCont
cont)  
  , [ TyArg {}, TyArg {} ] <- [ArgSpec]
rev_args
  = do { OutId
s <- FastString -> Kind -> Kind -> SimplM OutId
newId ([Char] -> FastString
fsLit [Char]
"s") Kind
Many Kind
realWorldStatePrimTy
       ; let (Kind
m,Kind
_,Kind
_) = Kind -> (Kind, Kind, Kind)
splitFunTy Kind
fun_ty
             env' :: SimplEnv
env'  = (SimplEnv
arg_se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env) SimplEnv -> [OutId] -> SimplEnv
`addNewInScopeIds` [OutId
s]
             ty' :: Kind
ty'   = SimplCont -> Kind
contResultType SimplCont
cont
             cont' :: SimplCont
cont' = ApplyToVal { sc_dup :: DupFlag
sc_dup = DupFlag
Simplified, sc_arg :: CoreExpr
sc_arg = OutId -> CoreExpr
forall b. OutId -> Expr b
Var OutId
s
                                , sc_env :: SimplEnv
sc_env = SimplEnv
env', sc_cont :: SimplCont
sc_cont = SimplCont
cont
                                , sc_hole_ty :: Kind
sc_hole_ty = Kind -> Kind -> Kind -> Kind
mkVisFunTy Kind
m Kind
realWorldStatePrimTy Kind
ty' }
                     
       ; CoreExpr
body' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
env' CoreExpr
arg SimplCont
cont'
       ; let arg' :: CoreExpr
arg'  = OutId -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam OutId
s CoreExpr
body'
             rr' :: Kind
rr'   = HasDebugCallStack => Kind -> Kind
Kind -> Kind
getRuntimeRep Kind
ty'
             call' :: CoreExpr
call' = CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps (OutId -> CoreExpr
forall b. OutId -> Expr b
Var OutId
fun_id) [Kind -> CoreExpr
forall b. Kind -> Expr b
mkTyArg Kind
rr', Kind -> CoreExpr
forall b. Kind -> Expr b
mkTyArg Kind
ty', CoreExpr
arg']
       ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, CoreExpr
call') }
rebuildCall SimplEnv
env ArgInfo
fun_info
            (ApplyToVal { sc_arg :: SimplCont -> CoreExpr
sc_arg = CoreExpr
arg, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
arg_se
                        , sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
dup_flag, sc_hole_ty :: SimplCont -> Kind
sc_hole_ty = Kind
fun_ty
                        , sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont })
  
  | DupFlag -> Bool
isSimplified DupFlag
dup_flag     
  = SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env (ArgInfo -> CoreExpr -> Kind -> ArgInfo
addValArgTo ArgInfo
fun_info CoreExpr
arg Kind
fun_ty) SimplCont
cont
  
  | ArgInfo -> Bool
isStrictArgInfo ArgInfo
fun_info
  , SimplMode -> Bool
sm_case_case (SimplEnv -> SimplMode
getMode SimplEnv
env)
  = 
    SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF (SimplEnv
arg_se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env) CoreExpr
arg
               (StrictArg { sc_fun :: ArgInfo
sc_fun = ArgInfo
fun_info, sc_fun_ty :: Kind
sc_fun_ty = Kind
fun_ty
                          , sc_dup :: DupFlag
sc_dup = DupFlag
Simplified
                          , sc_cont :: SimplCont
sc_cont = SimplCont
cont })
                
  
  | Bool
otherwise
        
        
        
        
  = do  { CoreExpr
arg' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC (SimplEnv
arg_se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env) CoreExpr
arg
                             (Kind -> CallCtxt -> SimplCont
mkLazyArgStop Kind
arg_ty (ArgInfo -> CallCtxt
lazyArgContext ArgInfo
fun_info))
        ; SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env (ArgInfo -> CoreExpr -> Kind -> ArgInfo
addValArgTo ArgInfo
fun_info  CoreExpr
arg' Kind
fun_ty) SimplCont
cont }
  where
    arg_ty :: Kind
arg_ty = Kind -> Kind
funArgTy Kind
fun_ty
rebuildCall SimplEnv
env (ArgInfo { ai_fun :: ArgInfo -> OutId
ai_fun = OutId
fun, ai_args :: ArgInfo -> [ArgSpec]
ai_args = [ArgSpec]
rev_args }) SimplCont
cont
  = SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (OutId -> [ArgSpec] -> CoreExpr
argInfoExpr OutId
fun [ArgSpec]
rev_args) SimplCont
cont
tryRules :: SimplEnv -> [CoreRule]
         -> Id -> [ArgSpec]
         -> SimplCont
         -> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
tryRules :: SimplEnv
-> [CoreRule]
-> OutId
-> [ArgSpec]
-> SimplCont
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
tryRules SimplEnv
env [CoreRule]
rules OutId
fn [ArgSpec]
args SimplCont
call_cont
  | [CoreRule] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CoreRule]
rules
  = Maybe (SimplEnv, CoreExpr, SimplCont)
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (SimplEnv, CoreExpr, SimplCont)
forall a. Maybe a
Nothing
  | Just (CoreRule
rule, CoreExpr
rule_rhs) <- RuleOpts
-> InScopeEnv
-> (Activation -> Bool)
-> OutId
-> [CoreExpr]
-> [CoreRule]
-> Maybe (CoreRule, CoreExpr)
lookupRule RuleOpts
ropts (SimplEnv -> InScopeEnv
getUnfoldingInRuleMatch SimplEnv
env)
                                        (SimplMode -> Activation -> Bool
activeRule (SimplEnv -> SimplMode
getMode SimplEnv
env)) OutId
fn
                                        ([ArgSpec] -> [CoreExpr]
argInfoAppArgs [ArgSpec]
args) [CoreRule]
rules
  
  = do { Tick -> SimplM ()
checkedTick (FastString -> Tick
RuleFired (CoreRule -> FastString
ruleName CoreRule
rule))
       ; let cont' :: SimplCont
cont' = SimplEnv -> [ArgSpec] -> SimplCont -> SimplCont
pushSimplifiedArgs SimplEnv
zapped_env
                                        (Int -> [ArgSpec] -> [ArgSpec]
forall a. Int -> [a] -> [a]
drop (CoreRule -> Int
ruleArity CoreRule
rule) [ArgSpec]
args)
                                        SimplCont
call_cont
                     
                     
             occ_anald_rhs :: CoreExpr
occ_anald_rhs = CoreExpr -> CoreExpr
occurAnalyseExpr CoreExpr
rule_rhs
                 
       ; CoreRule -> CoreExpr -> SimplM ()
dump CoreRule
rule CoreExpr
rule_rhs
       ; Maybe (SimplEnv, CoreExpr, SimplCont)
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
forall (m :: * -> *) a. Monad m => a -> m a
return ((SimplEnv, CoreExpr, SimplCont)
-> Maybe (SimplEnv, CoreExpr, SimplCont)
forall a. a -> Maybe a
Just (SimplEnv
zapped_env, CoreExpr
occ_anald_rhs, SimplCont
cont')) }
            
            
  | Bool
otherwise  
  = do { SimplM ()
nodump  
       ; Maybe (SimplEnv, CoreExpr, SimplCont)
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (SimplEnv, CoreExpr, SimplCont)
forall a. Maybe a
Nothing }
  where
    
    !ropts :: RuleOpts
ropts     = DynFlags -> RuleOpts
initRuleOpts DynFlags
dflags
    dflags :: DynFlags
dflags     = SimplEnv -> DynFlags
seDynFlags SimplEnv
env
    logger :: Logger
logger     = SimplEnv -> Logger
seLogger SimplEnv
env
    zapped_env :: SimplEnv
zapped_env = SimplEnv -> SimplEnv
zapSubstEnv SimplEnv
env  
    printRuleModule :: CoreRule -> SDoc
printRuleModule CoreRule
rule
      = SDoc -> SDoc
parens (SDoc -> (GenModule Unit -> SDoc) -> Maybe (GenModule Unit) -> SDoc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ([Char] -> SDoc
text [Char]
"BUILTIN")
                      (ModuleName -> SDoc
pprModuleName (ModuleName -> SDoc)
-> (GenModule Unit -> ModuleName) -> GenModule Unit -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenModule Unit -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName)
                      (CoreRule -> Maybe (GenModule Unit)
ruleModule CoreRule
rule))
    dump :: CoreRule -> CoreExpr -> SimplM ()
dump CoreRule
rule CoreExpr
rule_rhs
      | DumpFlag -> DynFlags -> Bool
dopt DumpFlag
Opt_D_dump_rule_rewrites DynFlags
dflags
      = DynFlags -> DumpFlag -> [Char] -> SDoc -> SimplM ()
log_rule DynFlags
dflags DumpFlag
Opt_D_dump_rule_rewrites [Char]
"Rule fired" (SDoc -> SimplM ()) -> SDoc -> SimplM ()
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
vcat
          [ [Char] -> SDoc
text [Char]
"Rule:" SDoc -> SDoc -> SDoc
<+> FastString -> SDoc
ftext (CoreRule -> FastString
ruleName CoreRule
rule)
          , [Char] -> SDoc
text [Char]
"Module:" SDoc -> SDoc -> SDoc
<+>  CoreRule -> SDoc
printRuleModule CoreRule
rule
          , [Char] -> SDoc
text [Char]
"Before:" SDoc -> SDoc -> SDoc
<+> SDoc -> Int -> SDoc -> SDoc
hang (OutId -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutId
fn) Int
2 ([SDoc] -> SDoc
sep ((ArgSpec -> SDoc) -> [ArgSpec] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map ArgSpec -> SDoc
forall a. Outputable a => a -> SDoc
ppr [ArgSpec]
args))
          , [Char] -> SDoc
text [Char]
"After: " SDoc -> SDoc -> SDoc
<+> SDoc -> Int -> SDoc -> SDoc
hang (CoreExpr -> SDoc
forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr CoreExpr
rule_rhs) Int
2
                               ([SDoc] -> SDoc
sep ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (ArgSpec -> SDoc) -> [ArgSpec] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map ArgSpec -> SDoc
forall a. Outputable a => a -> SDoc
ppr ([ArgSpec] -> [SDoc]) -> [ArgSpec] -> [SDoc]
forall a b. (a -> b) -> a -> b
$ Int -> [ArgSpec] -> [ArgSpec]
forall a. Int -> [a] -> [a]
drop (CoreRule -> Int
ruleArity CoreRule
rule) [ArgSpec]
args)
          , [Char] -> SDoc
text [Char]
"Cont:  " SDoc -> SDoc -> SDoc
<+> SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
call_cont ]
      | DumpFlag -> DynFlags -> Bool
dopt DumpFlag
Opt_D_dump_rule_firings DynFlags
dflags
      = DynFlags -> DumpFlag -> [Char] -> SDoc -> SimplM ()
log_rule DynFlags
dflags DumpFlag
Opt_D_dump_rule_firings [Char]
"Rule fired:" (SDoc -> SimplM ()) -> SDoc -> SimplM ()
forall a b. (a -> b) -> a -> b
$
          FastString -> SDoc
ftext (CoreRule -> FastString
ruleName CoreRule
rule)
            SDoc -> SDoc -> SDoc
<+> CoreRule -> SDoc
printRuleModule CoreRule
rule
      | Bool
otherwise
      = () -> SimplM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    nodump :: SimplM ()
nodump
      | DumpFlag -> DynFlags -> Bool
dopt DumpFlag
Opt_D_dump_rule_rewrites DynFlags
dflags
      = IO () -> SimplM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> SimplM ()) -> IO () -> SimplM ()
forall a b. (a -> b) -> a -> b
$
          Logger -> DynFlags -> DumpFlag -> IO ()
touchDumpFile Logger
logger DynFlags
dflags DumpFlag
Opt_D_dump_rule_rewrites
      | DumpFlag -> DynFlags -> Bool
dopt DumpFlag
Opt_D_dump_rule_firings DynFlags
dflags
      = IO () -> SimplM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> SimplM ()) -> IO () -> SimplM ()
forall a b. (a -> b) -> a -> b
$
          Logger -> DynFlags -> DumpFlag -> IO ()
touchDumpFile Logger
logger DynFlags
dflags DumpFlag
Opt_D_dump_rule_firings
      | Bool
otherwise
      = () -> SimplM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    log_rule :: DynFlags -> DumpFlag -> [Char] -> SDoc -> SimplM ()
log_rule DynFlags
dflags DumpFlag
flag [Char]
hdr SDoc
details
      = IO () -> SimplM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> SimplM ()) -> IO () -> SimplM ()
forall a b. (a -> b) -> a -> b
$ do
          let sty :: PprStyle
sty = PrintUnqualified -> PprStyle
mkDumpStyle PrintUnqualified
alwaysQualify
          Logger -> DumpAction
putDumpMsg Logger
logger DynFlags
dflags PprStyle
sty DumpFlag
flag [Char]
"" DumpFormat
FormatText (SDoc -> IO ()) -> SDoc -> IO ()
forall a b. (a -> b) -> a -> b
$
              [SDoc] -> SDoc
sep [[Char] -> SDoc
text [Char]
hdr, Int -> SDoc -> SDoc
nest Int
4 SDoc
details]
trySeqRules :: SimplEnv
            -> OutExpr -> InExpr   
            -> SimplCont
            -> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
trySeqRules :: SimplEnv
-> CoreExpr
-> CoreExpr
-> SimplCont
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
trySeqRules SimplEnv
in_env CoreExpr
scrut CoreExpr
rhs SimplCont
cont
  = do { RuleEnv
rule_base <- SimplM RuleEnv
getSimplRules
       ; SimplEnv
-> [CoreRule]
-> OutId
-> [ArgSpec]
-> SimplCont
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
tryRules SimplEnv
in_env (RuleEnv -> OutId -> [CoreRule]
getRules RuleEnv
rule_base OutId
seqId) OutId
seqId [ArgSpec]
out_args SimplCont
rule_cont }
  where
    no_cast_scrut :: CoreExpr
no_cast_scrut = CoreExpr -> CoreExpr
forall {b}. Expr b -> Expr b
drop_casts CoreExpr
scrut
    scrut_ty :: Kind
scrut_ty  = CoreExpr -> Kind
exprType CoreExpr
no_cast_scrut
    seq_id_ty :: Kind
seq_id_ty = OutId -> Kind
idType OutId
seqId                    
    res1_ty :: Kind
res1_ty   = HasDebugCallStack => Kind -> Kind -> Kind
Kind -> Kind -> Kind
piResultTy Kind
seq_id_ty Kind
rhs_rep    
    res2_ty :: Kind
res2_ty   = HasDebugCallStack => Kind -> Kind -> Kind
Kind -> Kind -> Kind
piResultTy Kind
res1_ty   Kind
scrut_ty   
    res3_ty :: Kind
res3_ty   = HasDebugCallStack => Kind -> Kind -> Kind
Kind -> Kind -> Kind
piResultTy Kind
res2_ty   Kind
rhs_ty     
    res4_ty :: Kind
res4_ty   = Kind -> Kind
funResultTy Kind
res3_ty             
    rhs_ty :: Kind
rhs_ty    = SimplEnv -> Kind -> Kind
substTy SimplEnv
in_env (CoreExpr -> Kind
exprType CoreExpr
rhs)
    rhs_rep :: Kind
rhs_rep   = HasDebugCallStack => Kind -> Kind
Kind -> Kind
getRuntimeRep Kind
rhs_ty
    out_args :: [ArgSpec]
out_args  = [ TyArg { as_arg_ty :: Kind
as_arg_ty  = Kind
rhs_rep
                        , as_hole_ty :: Kind
as_hole_ty = Kind
seq_id_ty }
                , TyArg { as_arg_ty :: Kind
as_arg_ty  = Kind
scrut_ty
                        , as_hole_ty :: Kind
as_hole_ty = Kind
res1_ty }
                , TyArg { as_arg_ty :: Kind
as_arg_ty  = Kind
rhs_ty
                        , as_hole_ty :: Kind
as_hole_ty = Kind
res2_ty }
                , ValArg { as_arg :: CoreExpr
as_arg = CoreExpr
no_cast_scrut
                         , as_dmd :: Demand
as_dmd = Demand
seqDmd
                         , as_hole_ty :: Kind
as_hole_ty = Kind
res3_ty } ]
    rule_cont :: SimplCont
rule_cont = ApplyToVal { sc_dup :: DupFlag
sc_dup = DupFlag
NoDup, sc_arg :: CoreExpr
sc_arg = CoreExpr
rhs
                           , sc_env :: SimplEnv
sc_env = SimplEnv
in_env, sc_cont :: SimplCont
sc_cont = SimplCont
cont
                           , sc_hole_ty :: Kind
sc_hole_ty = Kind
res4_ty }
    
    drop_casts :: Expr b -> Expr b
drop_casts (Cast Expr b
e Coercion
_) = Expr b -> Expr b
drop_casts Expr b
e
    drop_casts Expr b
e          = Expr b
e
rebuildCase, reallyRebuildCase
   :: SimplEnv
   -> OutExpr          
   -> InId             
   -> [InAlt]          
   -> SimplCont
   -> SimplM (SimplFloats, OutExpr)
rebuildCase :: SimplEnv
-> CoreExpr
-> OutId
-> [Alt OutId]
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
rebuildCase SimplEnv
env CoreExpr
scrut OutId
case_bndr [Alt OutId]
alts SimplCont
cont
  | Lit Literal
lit <- CoreExpr
scrut    
                        
  , Bool -> Bool
not (Literal -> Bool
litIsLifted Literal
lit)
  = do  { Tick -> SimplM ()
tick (OutId -> Tick
KnownBranch OutId
case_bndr)
        ; case AltCon -> [Alt OutId] -> Maybe (Alt OutId)
forall b. AltCon -> [Alt b] -> Maybe (Alt b)
findAlt (Literal -> AltCon
LitAlt Literal
lit) [Alt OutId]
alts of
            Maybe (Alt OutId)
Nothing             -> SimplEnv
-> OutId
-> [Alt OutId]
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
missingAlt SimplEnv
env OutId
case_bndr [Alt OutId]
alts SimplCont
cont
            Just (Alt AltCon
_ [OutId]
bs CoreExpr
rhs) -> SimplEnv
-> [FloatBind]
-> CoreExpr
-> [OutId]
-> CoreExpr
-> SimplM (SimplFloats, CoreExpr)
simple_rhs SimplEnv
env [] CoreExpr
scrut [OutId]
bs CoreExpr
rhs }
  | Just (InScopeSet
in_scope', [FloatBind]
wfloats, DataCon
con, [Kind]
ty_args, [CoreExpr]
other_args)
      <- InScopeEnv
-> CoreExpr
-> Maybe (InScopeSet, [FloatBind], DataCon, [Kind], [CoreExpr])
HasDebugCallStack =>
InScopeEnv
-> CoreExpr
-> Maybe (InScopeSet, [FloatBind], DataCon, [Kind], [CoreExpr])
exprIsConApp_maybe (SimplEnv -> InScopeEnv
getUnfoldingInRuleMatch SimplEnv
env) CoreExpr
scrut
        
        
  , let env0 :: SimplEnv
env0 = SimplEnv -> InScopeSet -> SimplEnv
setInScopeSet SimplEnv
env InScopeSet
in_scope'
  = do  { Tick -> SimplM ()
tick (OutId -> Tick
KnownBranch OutId
case_bndr)
        ; let scaled_wfloats :: [FloatBind]
scaled_wfloats = (FloatBind -> FloatBind) -> [FloatBind] -> [FloatBind]
forall a b. (a -> b) -> [a] -> [b]
map FloatBind -> FloatBind
scale_float [FloatBind]
wfloats
        ; case AltCon -> [Alt OutId] -> Maybe (Alt OutId)
forall b. AltCon -> [Alt b] -> Maybe (Alt b)
findAlt (DataCon -> AltCon
DataAlt DataCon
con) [Alt OutId]
alts of
            Maybe (Alt OutId)
Nothing  -> SimplEnv
-> OutId
-> [Alt OutId]
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
missingAlt SimplEnv
env0 OutId
case_bndr [Alt OutId]
alts SimplCont
cont
            Just (Alt AltCon
DEFAULT [OutId]
bs CoreExpr
rhs) -> let con_app :: CoreExpr
con_app = OutId -> CoreExpr
forall b. OutId -> Expr b
Var (DataCon -> OutId
dataConWorkId DataCon
con)
                                                 CoreExpr -> [Kind] -> CoreExpr
forall b. Expr b -> [Kind] -> Expr b
`mkTyApps` [Kind]
ty_args
                                                 CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
`mkApps`   [CoreExpr]
other_args
                                         in SimplEnv
-> [FloatBind]
-> CoreExpr
-> [OutId]
-> CoreExpr
-> SimplM (SimplFloats, CoreExpr)
simple_rhs SimplEnv
env0 [FloatBind]
scaled_wfloats CoreExpr
con_app [OutId]
bs CoreExpr
rhs
            Just (Alt AltCon
_ [OutId]
bs CoreExpr
rhs)       -> SimplEnv
-> CoreExpr
-> [FloatBind]
-> DataCon
-> [Kind]
-> [CoreExpr]
-> OutId
-> [OutId]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
knownCon SimplEnv
env0 CoreExpr
scrut [FloatBind]
scaled_wfloats DataCon
con [Kind]
ty_args [CoreExpr]
other_args
                                                  OutId
case_bndr [OutId]
bs CoreExpr
rhs SimplCont
cont
        }
  where
    simple_rhs :: SimplEnv
-> [FloatBind]
-> CoreExpr
-> [OutId]
-> CoreExpr
-> SimplM (SimplFloats, CoreExpr)
simple_rhs SimplEnv
env [FloatBind]
wfloats CoreExpr
scrut' [OutId]
bs CoreExpr
rhs =
      ASSERT( null bs )
      do { (SimplFloats
floats1, SimplEnv
env') <- SimplEnv -> OutId -> CoreExpr -> SimplM (SimplFloats, SimplEnv)
simplNonRecX SimplEnv
env OutId
case_bndr CoreExpr
scrut'
             
             
         ; (SimplFloats
floats2, CoreExpr
expr') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env' CoreExpr
rhs SimplCont
cont
         ; case [FloatBind]
wfloats of
             [] -> (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
expr')
             [FloatBind]
_ -> (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return
               
                   ( SimplEnv -> SimplFloats
emptyFloats SimplEnv
env,
                     [FloatBind] -> CoreExpr -> CoreExpr
GHC.Core.Make.wrapFloats [FloatBind]
wfloats (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$
                     SimplFloats -> CoreExpr -> CoreExpr
wrapFloats (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2) CoreExpr
expr' )}
    
    
    
    scale_float :: FloatBind -> FloatBind
scale_float (GHC.Core.Make.FloatCase CoreExpr
scrut OutId
case_bndr AltCon
con [OutId]
vars) =
      let
        scale_id :: OutId -> OutId
scale_id OutId
id = Kind -> OutId -> OutId
scaleVarBy Kind
holeScaling OutId
id
      in
      CoreExpr -> OutId -> AltCon -> [OutId] -> FloatBind
GHC.Core.Make.FloatCase CoreExpr
scrut (OutId -> OutId
scale_id OutId
case_bndr) AltCon
con ((OutId -> OutId) -> [OutId] -> [OutId]
forall a b. (a -> b) -> [a] -> [b]
map OutId -> OutId
scale_id [OutId]
vars)
    scale_float FloatBind
f = FloatBind
f
    holeScaling :: Kind
holeScaling = SimplCont -> Kind
contHoleScaling SimplCont
cont Kind -> Kind -> Kind
`mkMultMul` OutId -> Kind
idMult OutId
case_bndr
     
     
     
     
     
     
     
     
     
     
     
     
     
     
rebuildCase SimplEnv
env CoreExpr
scrut OutId
case_bndr alts :: [Alt OutId]
alts@[Alt AltCon
_ [OutId]
bndrs CoreExpr
rhs] SimplCont
cont
  
  
  
  
  
  
  
  | Bool
is_plain_seq
  , CoreExpr -> Bool
exprOkForSideEffects CoreExpr
scrut
          
          
          
          
   = SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
rhs SimplCont
cont
  
  
  
  
  
  | Bool
all_dead_bndrs
  , CoreExpr -> OutId -> Bool
doCaseToLet CoreExpr
scrut OutId
case_bndr
  = do { Tick -> SimplM ()
tick (OutId -> Tick
CaseElim OutId
case_bndr)
       ; (SimplFloats
floats1, SimplEnv
env') <- SimplEnv -> OutId -> CoreExpr -> SimplM (SimplFloats, SimplEnv)
simplNonRecX SimplEnv
env OutId
case_bndr CoreExpr
scrut
       ; (SimplFloats
floats2, CoreExpr
expr') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env' CoreExpr
rhs SimplCont
cont
       ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
expr') }
  
  
  
  
  | Bool
is_plain_seq
  = do { Maybe (SimplEnv, CoreExpr, SimplCont)
mb_rule <- SimplEnv
-> CoreExpr
-> CoreExpr
-> SimplCont
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
trySeqRules SimplEnv
env CoreExpr
scrut CoreExpr
rhs SimplCont
cont
       ; case Maybe (SimplEnv, CoreExpr, SimplCont)
mb_rule of
           Just (SimplEnv
env', CoreExpr
rule_rhs, SimplCont
cont') -> SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env' CoreExpr
rule_rhs SimplCont
cont'
           Maybe (SimplEnv, CoreExpr, SimplCont)
Nothing                      -> SimplEnv
-> CoreExpr
-> OutId
-> [Alt OutId]
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
reallyRebuildCase SimplEnv
env CoreExpr
scrut OutId
case_bndr [Alt OutId]
alts SimplCont
cont }
  where
    all_dead_bndrs :: Bool
all_dead_bndrs = (OutId -> Bool) -> [OutId] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all OutId -> Bool
isDeadBinder [OutId]
bndrs       
    is_plain_seq :: Bool
is_plain_seq   = Bool
all_dead_bndrs Bool -> Bool -> Bool
&& OutId -> Bool
isDeadBinder OutId
case_bndr 
rebuildCase SimplEnv
env CoreExpr
scrut OutId
case_bndr [Alt OutId]
alts SimplCont
cont
  = SimplEnv
-> CoreExpr
-> OutId
-> [Alt OutId]
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
reallyRebuildCase SimplEnv
env CoreExpr
scrut OutId
case_bndr [Alt OutId]
alts SimplCont
cont
doCaseToLet :: OutExpr          
            -> InId             
            -> Bool
doCaseToLet :: CoreExpr -> OutId -> Bool
doCaseToLet CoreExpr
scrut OutId
case_bndr
  | OutId -> Bool
isTyCoVar OutId
case_bndr    
  = CoreExpr -> Bool
forall {b}. Expr b -> Bool
isTyCoArg CoreExpr
scrut        
  | HasDebugCallStack => Kind -> Bool
Kind -> Bool
isUnliftedType (OutId -> Kind
idType OutId
case_bndr)
  = CoreExpr -> Bool
exprOkForSpeculation CoreExpr
scrut
  | Bool
otherwise  
  = CoreExpr -> Bool
exprIsHNF CoreExpr
scrut
    Bool -> Bool -> Bool
|| Demand -> Bool
isStrUsedDmd (OutId -> Demand
idDemandInfo OutId
case_bndr)
    
reallyRebuildCase :: SimplEnv
-> CoreExpr
-> OutId
-> [Alt OutId]
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
reallyRebuildCase SimplEnv
env CoreExpr
scrut OutId
case_bndr [Alt OutId]
alts SimplCont
cont
  | Bool -> Bool
not (SimplMode -> Bool
sm_case_case (SimplEnv -> SimplMode
getMode SimplEnv
env))
  = do { CoreExpr
case_expr <- SimplEnv
-> CoreExpr -> OutId -> [Alt OutId] -> SimplCont -> SimplM CoreExpr
simplAlts SimplEnv
env CoreExpr
scrut OutId
case_bndr [Alt OutId]
alts
                                (Kind -> SimplCont
mkBoringStop (SimplCont -> Kind
contHoleType SimplCont
cont))
       ; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env CoreExpr
case_expr SimplCont
cont }
  | Bool
otherwise
  = do { (SimplFloats
floats, SimplEnv
env', SimplCont
cont') <- SimplEnv
-> [Alt OutId]
-> SimplCont
-> SimplM (SimplFloats, SimplEnv, SimplCont)
mkDupableCaseCont SimplEnv
env [Alt OutId]
alts SimplCont
cont
       ; CoreExpr
case_expr <- SimplEnv
-> CoreExpr -> OutId -> [Alt OutId] -> SimplCont -> SimplM CoreExpr
simplAlts SimplEnv
env' CoreExpr
scrut
                                (Kind -> OutId -> OutId
scaleIdBy Kind
holeScaling OutId
case_bndr)
                                (Kind -> [Alt OutId] -> [Alt OutId]
scaleAltsBy Kind
holeScaling [Alt OutId]
alts)
                                SimplCont
cont'
       ; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, CoreExpr
case_expr) }
  where
    holeScaling :: Kind
holeScaling = SimplCont -> Kind
contHoleScaling SimplCont
cont
    
simplAlts :: SimplEnv
          -> OutExpr         
          -> InId            
          -> [InAlt]         
          -> SimplCont
          -> SimplM OutExpr  
simplAlts :: SimplEnv
-> CoreExpr -> OutId -> [Alt OutId] -> SimplCont -> SimplM CoreExpr
simplAlts SimplEnv
env0 CoreExpr
scrut OutId
case_bndr [Alt OutId]
alts SimplCont
cont'
  = do  { [Char] -> SDoc -> SimplM ()
traceSmpl [Char]
"simplAlts" ([SDoc] -> SDoc
vcat [ OutId -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutId
case_bndr
                                      , [Char] -> SDoc
text [Char]
"cont':" SDoc -> SDoc -> SDoc
<+> SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
cont'
                                      , [Char] -> SDoc
text [Char]
"in_scope" SDoc -> SDoc -> SDoc
<+> InScopeSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr (SimplEnv -> InScopeSet
seInScope SimplEnv
env0) ])
        ; (SimplEnv
env1, OutId
case_bndr1) <- SimplEnv -> OutId -> SimplM (SimplEnv, OutId)
simplBinder SimplEnv
env0 OutId
case_bndr
        ; let case_bndr2 :: OutId
case_bndr2 = OutId
case_bndr1 OutId -> Unfolding -> OutId
`setIdUnfolding` Unfolding
evaldUnfolding
              env2 :: SimplEnv
env2       = SimplEnv -> OutId -> SimplEnv
modifyInScope SimplEnv
env1 OutId
case_bndr2
              
        ; (FamInstEnv, FamInstEnv)
fam_envs <- SimplM (FamInstEnv, FamInstEnv)
getFamEnvs
        ; (SimplEnv
alt_env', CoreExpr
scrut', OutId
case_bndr') <- (FamInstEnv, FamInstEnv)
-> SimplEnv
-> CoreExpr
-> OutId
-> OutId
-> [Alt OutId]
-> SimplM (SimplEnv, CoreExpr, OutId)
improveSeq (FamInstEnv, FamInstEnv)
fam_envs SimplEnv
env2 CoreExpr
scrut
                                                       OutId
case_bndr OutId
case_bndr2 [Alt OutId]
alts
        ; ([AltCon]
imposs_deflt_cons, [Alt OutId]
in_alts) <- CoreExpr -> OutId -> [Alt OutId] -> SimplM ([AltCon], [Alt OutId])
prepareAlts CoreExpr
scrut' OutId
case_bndr' [Alt OutId]
alts
          
          
        ; [Alt OutId]
alts' <- (Alt OutId -> SimplM (Alt OutId))
-> [Alt OutId] -> SimplM [Alt OutId]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (SimplEnv
-> Maybe CoreExpr
-> [AltCon]
-> OutId
-> SimplCont
-> Alt OutId
-> SimplM (Alt OutId)
simplAlt SimplEnv
alt_env' (CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just CoreExpr
scrut') [AltCon]
imposs_deflt_cons OutId
case_bndr' SimplCont
cont') [Alt OutId]
in_alts
        ; 
        ; let alts_ty' :: Kind
alts_ty' = SimplCont -> Kind
contResultType SimplCont
cont'
        
        ; Kind -> ()
seqType Kind
alts_ty' () -> SimplM CoreExpr -> SimplM CoreExpr
`seq`
          DynFlags
-> CoreExpr -> OutId -> Kind -> [Alt OutId] -> SimplM CoreExpr
mkCase (SimplEnv -> DynFlags
seDynFlags SimplEnv
env0) CoreExpr
scrut' OutId
case_bndr' Kind
alts_ty' [Alt OutId]
alts' }
improveSeq :: (FamInstEnv, FamInstEnv) -> SimplEnv
           -> OutExpr -> InId -> OutId -> [InAlt]
           -> SimplM (SimplEnv, OutExpr, OutId)
improveSeq :: (FamInstEnv, FamInstEnv)
-> SimplEnv
-> CoreExpr
-> OutId
-> OutId
-> [Alt OutId]
-> SimplM (SimplEnv, CoreExpr, OutId)
improveSeq (FamInstEnv, FamInstEnv)
fam_envs SimplEnv
env CoreExpr
scrut OutId
case_bndr OutId
case_bndr1 [Alt AltCon
DEFAULT [OutId]
_ CoreExpr
_]
  | Just (Coercion
co, Kind
ty2) <- (FamInstEnv, FamInstEnv) -> Kind -> Maybe (Coercion, Kind)
topNormaliseType_maybe (FamInstEnv, FamInstEnv)
fam_envs (OutId -> Kind
idType OutId
case_bndr1)
  = do { OutId
case_bndr2 <- FastString -> Kind -> Kind -> SimplM OutId
newId ([Char] -> FastString
fsLit [Char]
"nt") Kind
Many Kind
ty2
        ; let rhs :: SimplSR
rhs  = CoreExpr -> Maybe Int -> SimplSR
DoneEx (OutId -> CoreExpr
forall b. OutId -> Expr b
Var OutId
case_bndr2 CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
`Cast` Coercion -> Coercion
mkSymCo Coercion
co) Maybe Int
forall a. Maybe a
Nothing
              env2 :: SimplEnv
env2 = SimplEnv -> OutId -> SimplSR -> SimplEnv
extendIdSubst SimplEnv
env OutId
case_bndr SimplSR
rhs
        ; (SimplEnv, CoreExpr, OutId) -> SimplM (SimplEnv, CoreExpr, OutId)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv
env2, CoreExpr
scrut CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
`Cast` Coercion
co, OutId
case_bndr2) }
improveSeq (FamInstEnv, FamInstEnv)
_ SimplEnv
env CoreExpr
scrut OutId
_ OutId
case_bndr1 [Alt OutId]
_
  = (SimplEnv, CoreExpr, OutId) -> SimplM (SimplEnv, CoreExpr, OutId)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv
env, CoreExpr
scrut, OutId
case_bndr1)
simplAlt :: SimplEnv
         -> Maybe OutExpr  
         -> [AltCon]       
                           
         -> OutId          
         -> SimplCont
         -> InAlt
         -> SimplM OutAlt
simplAlt :: SimplEnv
-> Maybe CoreExpr
-> [AltCon]
-> OutId
-> SimplCont
-> Alt OutId
-> SimplM (Alt OutId)
simplAlt SimplEnv
env Maybe CoreExpr
_ ![AltCon]
imposs_deflt_cons OutId
case_bndr' SimplCont
cont' (Alt AltCon
DEFAULT [OutId]
bndrs CoreExpr
rhs)
  = ASSERT( null bndrs )
    do  { let env' :: SimplEnv
env' = SimplEnv -> OutId -> Unfolding -> SimplEnv
addBinderUnfolding SimplEnv
env OutId
case_bndr'
                                        ([AltCon] -> Unfolding
mkOtherCon [AltCon]
imposs_deflt_cons)
                
        ; CoreExpr
rhs' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
env' CoreExpr
rhs SimplCont
cont'
        ; Alt OutId -> SimplM (Alt OutId)
forall (m :: * -> *) a. Monad m => a -> m a
return (AltCon -> [OutId] -> CoreExpr -> Alt OutId
forall b. AltCon -> [b] -> Expr b -> Alt b
Alt AltCon
DEFAULT [] CoreExpr
rhs') }
simplAlt SimplEnv
env Maybe CoreExpr
scrut' [AltCon]
_ OutId
case_bndr' SimplCont
cont' (Alt (LitAlt Literal
lit) [OutId]
bndrs CoreExpr
rhs)
  = ASSERT( null bndrs )
    do  { SimplEnv
env' <- SimplEnv -> Maybe CoreExpr -> OutId -> CoreExpr -> SimplM SimplEnv
addAltUnfoldings SimplEnv
env Maybe CoreExpr
scrut' OutId
case_bndr' (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
lit)
        ; CoreExpr
rhs' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
env' CoreExpr
rhs SimplCont
cont'
        ; Alt OutId -> SimplM (Alt OutId)
forall (m :: * -> *) a. Monad m => a -> m a
return (AltCon -> [OutId] -> CoreExpr -> Alt OutId
forall b. AltCon -> [b] -> Expr b -> Alt b
Alt (Literal -> AltCon
LitAlt Literal
lit) [] CoreExpr
rhs') }
simplAlt SimplEnv
env Maybe CoreExpr
scrut' [AltCon]
_ OutId
case_bndr' SimplCont
cont' (Alt (DataAlt DataCon
con) [OutId]
vs CoreExpr
rhs)
  = do  { 
          let vs_with_evals :: [OutId]
vs_with_evals = Maybe CoreExpr -> DataCon -> [OutId] -> [OutId]
addEvals Maybe CoreExpr
scrut' DataCon
con [OutId]
vs
        ; (SimplEnv
env', [OutId]
vs') <- SimplEnv -> [OutId] -> SimplM (SimplEnv, [OutId])
simplLamBndrs SimplEnv
env [OutId]
vs_with_evals
                
        ; let inst_tys' :: [Kind]
inst_tys' = Kind -> [Kind]
tyConAppArgs (OutId -> Kind
idType OutId
case_bndr')
              con_app :: OutExpr
              con_app :: CoreExpr
con_app   = DataCon -> [Kind] -> [OutId] -> CoreExpr
forall b. DataCon -> [Kind] -> [OutId] -> Expr b
mkConApp2 DataCon
con [Kind]
inst_tys' [OutId]
vs'
        ; SimplEnv
env'' <- SimplEnv -> Maybe CoreExpr -> OutId -> CoreExpr -> SimplM SimplEnv
addAltUnfoldings SimplEnv
env' Maybe CoreExpr
scrut' OutId
case_bndr' CoreExpr
con_app
        
        
        ; !CoreExpr
rhs' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
env'' CoreExpr
rhs SimplCont
cont'
        ; Alt OutId -> SimplM (Alt OutId)
forall (m :: * -> *) a. Monad m => a -> m a
return (AltCon -> [OutId] -> CoreExpr -> Alt OutId
forall b. AltCon -> [b] -> Expr b -> Alt b
Alt (DataCon -> AltCon
DataAlt DataCon
con) [OutId]
vs' CoreExpr
rhs') }
addEvals :: Maybe OutExpr -> DataCon -> [Id] -> [Id]
addEvals :: Maybe CoreExpr -> DataCon -> [OutId] -> [OutId]
addEvals Maybe CoreExpr
scrut DataCon
con [OutId]
vs
  
  | Just CoreExpr
scr <- Maybe CoreExpr
scrut
  , DataCon -> Bool
isUnboxedTupleDataCon DataCon
con
  , [OutId
s,OutId
x] <- [OutId]
vs
    
    
  , Just (Var OutId
f) <- Word -> CoreExpr -> Maybe CoreExpr
forall a. Word -> Expr a -> Maybe (Expr a)
stripNArgs Word
4 CoreExpr
scr
  , Just PrimOp
SeqOp <- OutId -> Maybe PrimOp
isPrimOpId_maybe OutId
f
  , let x' :: OutId
x' = StrictnessMark -> OutId -> OutId
zapIdOccInfoAndSetEvald StrictnessMark
MarkedStrict OutId
x
  = [OutId
s, OutId
x']
  
addEvals Maybe CoreExpr
_scrut DataCon
con [OutId]
vs = [OutId] -> [StrictnessMark] -> [OutId]
go [OutId]
vs [StrictnessMark]
the_strs
    where
      the_strs :: [StrictnessMark]
the_strs = DataCon -> [StrictnessMark]
dataConRepStrictness DataCon
con
      go :: [OutId] -> [StrictnessMark] -> [OutId]
go [] [] = []
      go (OutId
v:[OutId]
vs') [StrictnessMark]
strs | OutId -> Bool
isTyVar OutId
v = OutId
v OutId -> [OutId] -> [OutId]
forall a. a -> [a] -> [a]
: [OutId] -> [StrictnessMark] -> [OutId]
go [OutId]
vs' [StrictnessMark]
strs
      go (OutId
v:[OutId]
vs') (StrictnessMark
str:[StrictnessMark]
strs) = StrictnessMark -> OutId -> OutId
zapIdOccInfoAndSetEvald StrictnessMark
str OutId
v OutId -> [OutId] -> [OutId]
forall a. a -> [a] -> [a]
: [OutId] -> [StrictnessMark] -> [OutId]
go [OutId]
vs' [StrictnessMark]
strs
      go [OutId]
_ [StrictnessMark]
_ = [Char] -> SDoc -> [OutId]
forall a. HasCallStack => [Char] -> SDoc -> a
pprPanic [Char]
"Simplify.addEvals"
                (DataCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr DataCon
con SDoc -> SDoc -> SDoc
$$
                 [OutId] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [OutId]
vs  SDoc -> SDoc -> SDoc
$$
                 [SDoc] -> SDoc
forall {t :: * -> *} {a}.
(Outputable (t a), Foldable t) =>
t a -> SDoc
ppr_with_length ((StrictnessMark -> SDoc) -> [StrictnessMark] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map StrictnessMark -> SDoc
strdisp [StrictnessMark]
the_strs) SDoc -> SDoc -> SDoc
$$
                 [Scaled Kind] -> SDoc
forall {t :: * -> *} {a}.
(Outputable (t a), Foldable t) =>
t a -> SDoc
ppr_with_length (DataCon -> [Scaled Kind]
dataConRepArgTys DataCon
con) SDoc -> SDoc -> SDoc
$$
                 [StrictnessMark] -> SDoc
forall {t :: * -> *} {a}.
(Outputable (t a), Foldable t) =>
t a -> SDoc
ppr_with_length (DataCon -> [StrictnessMark]
dataConRepStrictness DataCon
con))
        where
          ppr_with_length :: t a -> SDoc
ppr_with_length t a
list
            = t a -> SDoc
forall a. Outputable a => a -> SDoc
ppr t a
list SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
parens ([Char] -> SDoc
text [Char]
"length =" SDoc -> SDoc -> SDoc
<+> Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr (t a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length t a
list))
          strdisp :: StrictnessMark -> SDoc
strdisp StrictnessMark
MarkedStrict = [Char] -> SDoc
text [Char]
"MarkedStrict"
          strdisp StrictnessMark
NotMarkedStrict = [Char] -> SDoc
text [Char]
"NotMarkedStrict"
zapIdOccInfoAndSetEvald :: StrictnessMark -> Id -> Id
zapIdOccInfoAndSetEvald :: StrictnessMark -> OutId -> OutId
zapIdOccInfoAndSetEvald StrictnessMark
str OutId
v =
  StrictnessMark -> OutId -> OutId
setCaseBndrEvald StrictnessMark
str (OutId -> OutId) -> OutId -> OutId
forall a b. (a -> b) -> a -> b
$ 
  OutId -> OutId
zapIdOccInfo OutId
v         
                         
addAltUnfoldings :: SimplEnv -> Maybe OutExpr -> OutId -> OutExpr -> SimplM SimplEnv
addAltUnfoldings :: SimplEnv -> Maybe CoreExpr -> OutId -> CoreExpr -> SimplM SimplEnv
addAltUnfoldings SimplEnv
env Maybe CoreExpr
scrut OutId
case_bndr CoreExpr
con_app
  = do { let con_app_unf :: Unfolding
con_app_unf = CoreExpr -> Unfolding
mk_simple_unf CoreExpr
con_app
             env1 :: SimplEnv
env1 = SimplEnv -> OutId -> Unfolding -> SimplEnv
addBinderUnfolding SimplEnv
env OutId
case_bndr Unfolding
con_app_unf
             
             env2 :: SimplEnv
env2 | Kind
Many <- OutId -> Kind
idMult OutId
case_bndr = case Maybe CoreExpr
scrut of
                      Just (Var OutId
v)           -> SimplEnv -> OutId -> Unfolding -> SimplEnv
addBinderUnfolding SimplEnv
env1 OutId
v Unfolding
con_app_unf
                      Just (Cast (Var OutId
v) Coercion
co) -> SimplEnv -> OutId -> Unfolding -> SimplEnv
addBinderUnfolding SimplEnv
env1 OutId
v (Unfolding -> SimplEnv) -> Unfolding -> SimplEnv
forall a b. (a -> b) -> a -> b
$
                                                CoreExpr -> Unfolding
mk_simple_unf (CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
con_app (Coercion -> Coercion
mkSymCo Coercion
co))
                      Maybe CoreExpr
_                      -> SimplEnv
env1
                  | Bool
otherwise = SimplEnv
env1
       ; [Char] -> SDoc -> SimplM ()
traceSmpl [Char]
"addAltUnf" ([SDoc] -> SDoc
vcat [OutId -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutId
case_bndr SDoc -> SDoc -> SDoc
<+> Maybe CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr Maybe CoreExpr
scrut, CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
con_app])
       ; SimplEnv -> SimplM SimplEnv
forall (m :: * -> *) a. Monad m => a -> m a
return SimplEnv
env2 }
  where
    
    !opts :: UnfoldingOpts
opts = SimplEnv -> UnfoldingOpts
seUnfoldingOpts SimplEnv
env
    mk_simple_unf :: CoreExpr -> Unfolding
mk_simple_unf = UnfoldingOpts -> CoreExpr -> Unfolding
mkSimpleUnfolding UnfoldingOpts
opts
addBinderUnfolding :: SimplEnv -> Id -> Unfolding -> SimplEnv
addBinderUnfolding :: SimplEnv -> OutId -> Unfolding -> SimplEnv
addBinderUnfolding SimplEnv
env OutId
bndr Unfolding
unf
  | Bool
debugIsOn, Just CoreExpr
tmpl <- Unfolding -> Maybe CoreExpr
maybeUnfoldingTemplate Unfolding
unf
  = WARN( not (eqType (idType bndr) (exprType tmpl)),
          ppr bndr $$ ppr (idType bndr) $$ ppr tmpl $$ ppr (exprType tmpl) )
    SimplEnv -> OutId -> SimplEnv
modifyInScope SimplEnv
env (OutId
bndr OutId -> Unfolding -> OutId
`setIdUnfolding` Unfolding
unf)
  | Bool
otherwise
  = SimplEnv -> OutId -> SimplEnv
modifyInScope SimplEnv
env (OutId
bndr OutId -> Unfolding -> OutId
`setIdUnfolding` Unfolding
unf)
zapBndrOccInfo :: Bool -> Id -> Id
zapBndrOccInfo :: Bool -> OutId -> OutId
zapBndrOccInfo Bool
keep_occ_info OutId
pat_id
  | Bool
keep_occ_info = OutId
pat_id
  | Bool
otherwise     = OutId -> OutId
zapIdOccInfo OutId
pat_id
knownCon :: SimplEnv
         -> OutExpr                                           
         -> [FloatBind] -> DataCon -> [OutType] -> [OutExpr]  
         -> InId -> [InBndr] -> InExpr                        
         -> SimplCont
         -> SimplM (SimplFloats, OutExpr)
knownCon :: SimplEnv
-> CoreExpr
-> [FloatBind]
-> DataCon
-> [Kind]
-> [CoreExpr]
-> OutId
-> [OutId]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
knownCon SimplEnv
env CoreExpr
scrut [FloatBind]
dc_floats DataCon
dc [Kind]
dc_ty_args [CoreExpr]
dc_args OutId
bndr [OutId]
bs CoreExpr
rhs SimplCont
cont
  = do  { (SimplFloats
floats1, SimplEnv
env1)  <- SimplEnv -> [OutId] -> [CoreExpr] -> SimplM (SimplFloats, SimplEnv)
bind_args SimplEnv
env [OutId]
bs [CoreExpr]
dc_args
        ; (SimplFloats
floats2, SimplEnv
env2)  <- SimplEnv -> SimplM (SimplFloats, SimplEnv)
bind_case_bndr SimplEnv
env1
        ; (SimplFloats
floats3, CoreExpr
expr') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env2 CoreExpr
rhs SimplCont
cont
        ; case [FloatBind]
dc_floats of
            [] ->
              (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats3, CoreExpr
expr')
            [FloatBind]
_ ->
              (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return ( SimplEnv -> SimplFloats
emptyFloats SimplEnv
env
               
                     , [FloatBind] -> CoreExpr -> CoreExpr
GHC.Core.Make.wrapFloats [FloatBind]
dc_floats (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$
                       SimplFloats -> CoreExpr -> CoreExpr
wrapFloats (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats3) CoreExpr
expr') }
  where
    zap_occ :: OutId -> OutId
zap_occ = Bool -> OutId -> OutId
zapBndrOccInfo (OutId -> Bool
isDeadBinder OutId
bndr)    
                  
    bind_args :: SimplEnv -> [OutId] -> [CoreExpr] -> SimplM (SimplFloats, SimplEnv)
bind_args SimplEnv
env' [] [CoreExpr]
_  = (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env', SimplEnv
env')
    bind_args SimplEnv
env' (OutId
b:[OutId]
bs') (Type Kind
ty : [CoreExpr]
args)
      = ASSERT( isTyVar b )
        SimplEnv -> [OutId] -> [CoreExpr] -> SimplM (SimplFloats, SimplEnv)
bind_args (SimplEnv -> OutId -> Kind -> SimplEnv
extendTvSubst SimplEnv
env' OutId
b Kind
ty) [OutId]
bs' [CoreExpr]
args
    bind_args SimplEnv
env' (OutId
b:[OutId]
bs') (Coercion Coercion
co : [CoreExpr]
args)
      = ASSERT( isCoVar b )
        SimplEnv -> [OutId] -> [CoreExpr] -> SimplM (SimplFloats, SimplEnv)
bind_args (SimplEnv -> OutId -> Coercion -> SimplEnv
extendCvSubst SimplEnv
env' OutId
b Coercion
co) [OutId]
bs' [CoreExpr]
args
    bind_args SimplEnv
env' (OutId
b:[OutId]
bs') (CoreExpr
arg : [CoreExpr]
args)
      = ASSERT( isId b )
        do { let b' :: OutId
b' = OutId -> OutId
zap_occ OutId
b
             
             
             
             
             
           ; (SimplFloats
floats1, SimplEnv
env2) <- SimplEnv -> OutId -> CoreExpr -> SimplM (SimplFloats, SimplEnv)
simplNonRecX SimplEnv
env' OutId
b' CoreExpr
arg  
           ; (SimplFloats
floats2, SimplEnv
env3)  <- SimplEnv -> [OutId] -> [CoreExpr] -> SimplM (SimplFloats, SimplEnv)
bind_args SimplEnv
env2 [OutId]
bs' [CoreExpr]
args
           ; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, SimplEnv
env3) }
    bind_args SimplEnv
_ [OutId]
_ [CoreExpr]
_ =
      [Char] -> SDoc -> SimplM (SimplFloats, SimplEnv)
forall a. HasCallStack => [Char] -> SDoc -> a
pprPanic [Char]
"bind_args" (SDoc -> SimplM (SimplFloats, SimplEnv))
-> SDoc -> SimplM (SimplFloats, SimplEnv)
forall a b. (a -> b) -> a -> b
$ DataCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr DataCon
dc SDoc -> SDoc -> SDoc
$$ [OutId] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [OutId]
bs SDoc -> SDoc -> SDoc
$$ [CoreExpr] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [CoreExpr]
dc_args SDoc -> SDoc -> SDoc
$$
                             [Char] -> SDoc
text [Char]
"scrut:" SDoc -> SDoc -> SDoc
<+> CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
scrut
       
       
       
       
       
       
       
    bind_case_bndr :: SimplEnv -> SimplM (SimplFloats, SimplEnv)
bind_case_bndr SimplEnv
env
      | OutId -> Bool
isDeadBinder OutId
bndr   = (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv
env)
      | CoreExpr -> Bool
exprIsTrivial CoreExpr
scrut = (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env
                                     , SimplEnv -> OutId -> SimplSR -> SimplEnv
extendIdSubst SimplEnv
env OutId
bndr (CoreExpr -> Maybe Int -> SimplSR
DoneEx CoreExpr
scrut Maybe Int
forall a. Maybe a
Nothing))
      | Bool
otherwise           = do { [CoreExpr]
dc_args <- (OutId -> SimplM CoreExpr) -> [OutId] -> SimplM [CoreExpr]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (SimplEnv -> OutId -> SimplM CoreExpr
simplVar SimplEnv
env) [OutId]
bs
                                         
                                         
                                 ; let con_app :: CoreExpr
con_app = OutId -> CoreExpr
forall b. OutId -> Expr b
Var (DataCon -> OutId
dataConWorkId DataCon
dc)
                                                 CoreExpr -> [Kind] -> CoreExpr
forall b. Expr b -> [Kind] -> Expr b
`mkTyApps` [Kind]
dc_ty_args
                                                 CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
`mkApps`   [CoreExpr]
dc_args
                                 ; SimplEnv -> OutId -> CoreExpr -> SimplM (SimplFloats, SimplEnv)
simplNonRecX SimplEnv
env OutId
bndr CoreExpr
con_app }
missingAlt :: SimplEnv -> Id -> [InAlt] -> SimplCont
           -> SimplM (SimplFloats, OutExpr)
                
                
                
                
                
missingAlt :: SimplEnv
-> OutId
-> [Alt OutId]
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
missingAlt SimplEnv
env OutId
case_bndr [Alt OutId]
_ SimplCont
cont
  = WARN( True, text "missingAlt" <+> ppr case_bndr )
    
    let cont_ty :: Kind
cont_ty = SimplCont -> Kind
contResultType SimplCont
cont
    in Kind -> ()
seqType Kind
cont_ty ()
-> SimplM (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
`seq`
       (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, Kind -> CoreExpr
mkImpossibleExpr Kind
cont_ty)
mkDupableCaseCont :: SimplEnv -> [InAlt] -> SimplCont
                  -> SimplM ( SimplFloats  
                            , SimplEnv     
                            , SimplCont)
mkDupableCaseCont :: SimplEnv
-> [Alt OutId]
-> SimplCont
-> SimplM (SimplFloats, SimplEnv, SimplCont)
mkDupableCaseCont SimplEnv
env [Alt OutId]
alts SimplCont
cont
  | [Alt OutId] -> Bool
altsWouldDup [Alt OutId]
alts = do { (SimplFloats
floats, SimplCont
cont) <- SimplEnv -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableCont SimplEnv
env SimplCont
cont
                           ; let env' :: SimplEnv
env' = SimplEnv -> SimplEnv
bumpCaseDepth (SimplEnv -> SimplEnv) -> SimplEnv -> SimplEnv
forall a b. (a -> b) -> a -> b
$
                                        SimplEnv
env SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
floats
                           ; (SimplFloats, SimplEnv, SimplCont)
-> SimplM (SimplFloats, SimplEnv, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, SimplEnv
env', SimplCont
cont) }
  | Bool
otherwise         = (SimplFloats, SimplEnv, SimplCont)
-> SimplM (SimplFloats, SimplEnv, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv
env, SimplCont
cont)
altsWouldDup :: [InAlt] -> Bool 
altsWouldDup :: [Alt OutId] -> Bool
altsWouldDup []  = Bool
False        
altsWouldDup [Alt OutId
_] = Bool
False
altsWouldDup (Alt OutId
alt:[Alt OutId]
alts)
  | Alt OutId -> Bool
is_bot_alt Alt OutId
alt = [Alt OutId] -> Bool
altsWouldDup [Alt OutId]
alts
  | Bool
otherwise      = Bool -> Bool
not ((Alt OutId -> Bool) -> [Alt OutId] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Alt OutId -> Bool
is_bot_alt [Alt OutId]
alts)
    
  where
    is_bot_alt :: Alt OutId -> Bool
is_bot_alt (Alt AltCon
_ [OutId]
_ CoreExpr
rhs) = CoreExpr -> Bool
exprIsDeadEnd CoreExpr
rhs
mkDupableCont :: SimplEnv
              -> SimplCont
              -> SimplM ( SimplFloats  
                                       
                        , SimplCont)   
mkDupableCont :: SimplEnv -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableCont SimplEnv
env SimplCont
cont
  = SimplEnv
-> [Demand] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableContWithDmds SimplEnv
env (Demand -> [Demand]
forall a. a -> [a]
repeat Demand
topDmd) SimplCont
cont
mkDupableContWithDmds
   :: SimplEnv  -> [Demand]  
   -> SimplCont -> SimplM ( SimplFloats, SimplCont)
mkDupableContWithDmds :: SimplEnv
-> [Demand] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableContWithDmds SimplEnv
env [Demand]
_ SimplCont
cont
  | SimplCont -> Bool
contIsDupable SimplCont
cont
  = (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplCont
cont)
mkDupableContWithDmds SimplEnv
_ [Demand]
_ (Stop {}) = [Char] -> SimplM (SimplFloats, SimplCont)
forall a. [Char] -> a
panic [Char]
"mkDupableCont"     
mkDupableContWithDmds SimplEnv
env [Demand]
dmds (CastIt Coercion
ty SimplCont
cont)
  = do  { (SimplFloats
floats, SimplCont
cont') <- SimplEnv
-> [Demand] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableContWithDmds SimplEnv
env [Demand]
dmds SimplCont
cont
        ; (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, Coercion -> SimplCont -> SimplCont
CastIt Coercion
ty SimplCont
cont') }
mkDupableContWithDmds SimplEnv
env [Demand]
dmds (TickIt CoreTickish
t SimplCont
cont)
  = do  { (SimplFloats
floats, SimplCont
cont') <- SimplEnv
-> [Demand] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableContWithDmds SimplEnv
env [Demand]
dmds SimplCont
cont
        ; (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, CoreTickish -> SimplCont -> SimplCont
TickIt CoreTickish
t SimplCont
cont') }
mkDupableContWithDmds SimplEnv
env [Demand]
_
     (StrictBind { sc_bndr :: SimplCont -> OutId
sc_bndr = OutId
bndr, sc_bndrs :: SimplCont -> [OutId]
sc_bndrs = [OutId]
bndrs
                 , sc_body :: SimplCont -> CoreExpr
sc_body = CoreExpr
body, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
se, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont})
  = do { let sb_env :: SimplEnv
sb_env = SimplEnv
se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env
       ; (SimplEnv
sb_env1, OutId
bndr')      <- SimplEnv -> OutId -> SimplM (SimplEnv, OutId)
simplBinder SimplEnv
sb_env OutId
bndr
       ; (SimplFloats
floats1, CoreExpr
join_inner) <- SimplEnv
-> [OutId]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
sb_env1 [OutId]
bndrs CoreExpr
body SimplCont
cont
          
          
       ; let join_body :: CoreExpr
join_body = SimplFloats -> CoreExpr -> CoreExpr
wrapFloats SimplFloats
floats1 CoreExpr
join_inner
             res_ty :: Kind
res_ty    = SimplCont -> Kind
contResultType SimplCont
cont
       ; SimplEnv
-> OutId -> CoreExpr -> Kind -> SimplM (SimplFloats, SimplCont)
mkDupableStrictBind SimplEnv
env OutId
bndr' CoreExpr
join_body Kind
res_ty }
mkDupableContWithDmds SimplEnv
env [Demand]
_
    (StrictArg { sc_fun :: SimplCont -> ArgInfo
sc_fun = ArgInfo
fun, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont
               , sc_fun_ty :: SimplCont -> Kind
sc_fun_ty = Kind
fun_ty })
  
  | Maybe DataCon -> Bool
forall a. Maybe a -> Bool
isNothing (OutId -> Maybe DataCon
isDataConId_maybe (ArgInfo -> OutId
ai_fun ArgInfo
fun))
  , SimplCont -> Bool
thumbsUpPlanA SimplCont
cont  
  = 
    do { let (Demand
_ : [Demand]
dmds) = ArgInfo -> [Demand]
ai_dmds ArgInfo
fun
       ; (SimplFloats
floats1, SimplCont
cont')  <- SimplEnv
-> [Demand] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableContWithDmds SimplEnv
env [Demand]
dmds SimplCont
cont
                              
                              
       ; ([LetFloats]
floats_s, [ArgSpec]
args') <- (ArgSpec -> SimplM (LetFloats, ArgSpec))
-> [ArgSpec] -> SimplM ([LetFloats], [ArgSpec])
forall (m :: * -> *) a b c.
Applicative m =>
(a -> m (b, c)) -> [a] -> m ([b], [c])
mapAndUnzipM (SimplMode -> ArgSpec -> SimplM (LetFloats, ArgSpec)
makeTrivialArg (SimplEnv -> SimplMode
getMode SimplEnv
env))
                                           (ArgInfo -> [ArgSpec]
ai_args ArgInfo
fun)
       ; (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return ( (SimplFloats -> LetFloats -> SimplFloats)
-> SimplFloats -> [LetFloats] -> SimplFloats
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' SimplFloats -> LetFloats -> SimplFloats
addLetFloats SimplFloats
floats1 [LetFloats]
floats_s
                , StrictArg { sc_fun :: ArgInfo
sc_fun = ArgInfo
fun { ai_args :: [ArgSpec]
ai_args = [ArgSpec]
args' }
                            , sc_cont :: SimplCont
sc_cont = SimplCont
cont'
                            , sc_fun_ty :: Kind
sc_fun_ty = Kind
fun_ty
                            , sc_dup :: DupFlag
sc_dup = DupFlag
OkToDup} ) }
  | Bool
otherwise
  = 
    
    
    do { let rhs_ty :: Kind
rhs_ty       = SimplCont -> Kind
contResultType SimplCont
cont
             (Kind
m,Kind
arg_ty,Kind
_) = Kind -> (Kind, Kind, Kind)
splitFunTy Kind
fun_ty
       ; OutId
arg_bndr <- FastString -> Kind -> Kind -> SimplM OutId
newId ([Char] -> FastString
fsLit [Char]
"arg") Kind
m Kind
arg_ty
       ; let env' :: SimplEnv
env' = SimplEnv
env SimplEnv -> [OutId] -> SimplEnv
`addNewInScopeIds` [OutId
arg_bndr]
       ; (SimplFloats
floats, CoreExpr
join_rhs) <- SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env' (ArgInfo -> CoreExpr -> Kind -> ArgInfo
addValArgTo ArgInfo
fun (OutId -> CoreExpr
forall b. OutId -> Expr b
Var OutId
arg_bndr) Kind
fun_ty) SimplCont
cont
       ; SimplEnv
-> OutId -> CoreExpr -> Kind -> SimplM (SimplFloats, SimplCont)
mkDupableStrictBind SimplEnv
env' OutId
arg_bndr (SimplFloats -> CoreExpr -> CoreExpr
wrapFloats SimplFloats
floats CoreExpr
join_rhs) Kind
rhs_ty }
  where
    thumbsUpPlanA :: SimplCont -> Bool
thumbsUpPlanA (StrictArg {})               = Bool
False
    thumbsUpPlanA (CastIt Coercion
_ SimplCont
k)                 = SimplCont -> Bool
thumbsUpPlanA SimplCont
k
    thumbsUpPlanA (TickIt CoreTickish
_ SimplCont
k)                 = SimplCont -> Bool
thumbsUpPlanA SimplCont
k
    thumbsUpPlanA (ApplyToVal { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = SimplCont -> Bool
thumbsUpPlanA SimplCont
k
    thumbsUpPlanA (ApplyToTy  { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = SimplCont -> Bool
thumbsUpPlanA SimplCont
k
    thumbsUpPlanA (Select {})                  = Bool
True
    thumbsUpPlanA (StrictBind {})              = Bool
True
    thumbsUpPlanA (Stop {})                    = Bool
True
mkDupableContWithDmds SimplEnv
env [Demand]
dmds
    (ApplyToTy { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont, sc_arg_ty :: SimplCont -> Kind
sc_arg_ty = Kind
arg_ty, sc_hole_ty :: SimplCont -> Kind
sc_hole_ty = Kind
hole_ty })
  = do  { (SimplFloats
floats, SimplCont
cont') <- SimplEnv
-> [Demand] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableContWithDmds SimplEnv
env [Demand]
dmds SimplCont
cont
        ; (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, ApplyToTy { sc_cont :: SimplCont
sc_cont = SimplCont
cont'
                                    , sc_arg_ty :: Kind
sc_arg_ty = Kind
arg_ty, sc_hole_ty :: Kind
sc_hole_ty = Kind
hole_ty }) }
mkDupableContWithDmds SimplEnv
env [Demand]
dmds
    (ApplyToVal { sc_arg :: SimplCont -> CoreExpr
sc_arg = CoreExpr
arg, sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
dup, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
se
                , sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont, sc_hole_ty :: SimplCont -> Kind
sc_hole_ty = Kind
hole_ty })
  =     
        
        
        
        
    do  { let (Demand
dmd:[Demand]
_) = [Demand]
dmds   
        ; (SimplFloats
floats1, SimplCont
cont') <- SimplEnv
-> [Demand] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableContWithDmds SimplEnv
env [Demand]
dmds SimplCont
cont
        ; let env' :: SimplEnv
env' = SimplEnv
env SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
floats1
        ; (DupFlag
_, SimplEnv
se', CoreExpr
arg') <- SimplEnv
-> DupFlag
-> SimplEnv
-> CoreExpr
-> SimplM (DupFlag, SimplEnv, CoreExpr)
simplArg SimplEnv
env' DupFlag
dup SimplEnv
se CoreExpr
arg
        ; (LetFloats
let_floats2, CoreExpr
arg'') <- SimplMode
-> TopLevelFlag
-> Demand
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
makeTrivial (SimplEnv -> SimplMode
getMode SimplEnv
env) TopLevelFlag
NotTopLevel Demand
dmd ([Char] -> FastString
fsLit [Char]
"karg") CoreExpr
arg'
        ; let all_floats :: SimplFloats
all_floats = SimplFloats
floats1 SimplFloats -> LetFloats -> SimplFloats
`addLetFloats` LetFloats
let_floats2
        ; (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return ( SimplFloats
all_floats
                 , ApplyToVal { sc_arg :: CoreExpr
sc_arg = CoreExpr
arg''
                              , sc_env :: SimplEnv
sc_env = SimplEnv
se' SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
all_floats
                                         
                                         
                                         
                                         
                              , sc_dup :: DupFlag
sc_dup = DupFlag
OkToDup, sc_cont :: SimplCont
sc_cont = SimplCont
cont'
                              , sc_hole_ty :: Kind
sc_hole_ty = Kind
hole_ty }) }
mkDupableContWithDmds SimplEnv
env [Demand]
_
    (Select { sc_bndr :: SimplCont -> OutId
sc_bndr = OutId
case_bndr, sc_alts :: SimplCont -> [Alt OutId]
sc_alts = [Alt OutId]
alts, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
se, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont })
  =     
        
        
        
        
    do  { Tick -> SimplM ()
tick (OutId -> Tick
CaseOfCase OutId
case_bndr)
        ; (SimplFloats
floats, SimplEnv
alt_env, SimplCont
alt_cont) <- SimplEnv
-> [Alt OutId]
-> SimplCont
-> SimplM (SimplFloats, SimplEnv, SimplCont)
mkDupableCaseCont (SimplEnv
se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env) [Alt OutId]
alts SimplCont
cont
                
                
                
        ; let cont_scaling :: Kind
cont_scaling = SimplCont -> Kind
contHoleScaling SimplCont
cont
          
        ; (SimplEnv
alt_env', OutId
case_bndr') <- SimplEnv -> OutId -> SimplM (SimplEnv, OutId)
simplBinder SimplEnv
alt_env (Kind -> OutId -> OutId
scaleIdBy Kind
cont_scaling OutId
case_bndr)
        ; [Alt OutId]
alts' <- (Alt OutId -> SimplM (Alt OutId))
-> [Alt OutId] -> SimplM [Alt OutId]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (SimplEnv
-> Maybe CoreExpr
-> [AltCon]
-> OutId
-> SimplCont
-> Alt OutId
-> SimplM (Alt OutId)
simplAlt SimplEnv
alt_env' Maybe CoreExpr
forall a. Maybe a
Nothing [] OutId
case_bndr' SimplCont
alt_cont) (Kind -> [Alt OutId] -> [Alt OutId]
scaleAltsBy Kind
cont_scaling [Alt OutId]
alts)
        
                
                
                
                
                
                
                
                
        
        
        ; (JoinFloats
join_floats, [Alt OutId]
alts'') <- (JoinFloats -> Alt OutId -> SimplM (JoinFloats, Alt OutId))
-> JoinFloats -> [Alt OutId] -> SimplM (JoinFloats, [Alt OutId])
forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM (Platform
-> OutId
-> JoinFloats
-> Alt OutId
-> SimplM (JoinFloats, Alt OutId)
mkDupableAlt (DynFlags -> Platform
targetPlatform (SimplEnv -> DynFlags
seDynFlags SimplEnv
env)) OutId
case_bndr')
                                              JoinFloats
emptyJoinFloats [Alt OutId]
alts'
        ; let all_floats :: SimplFloats
all_floats = SimplFloats
floats SimplFloats -> JoinFloats -> SimplFloats
`addJoinFloats` JoinFloats
join_floats
                           
        ; (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
all_floats
                 , Select { sc_dup :: DupFlag
sc_dup  = DupFlag
OkToDup
                          , sc_bndr :: OutId
sc_bndr = OutId
case_bndr'
                          , sc_alts :: [Alt OutId]
sc_alts = [Alt OutId]
alts''
                          , sc_env :: SimplEnv
sc_env  = SimplEnv -> SimplEnv
zapSubstEnv SimplEnv
se SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
all_floats
                                      
                          , sc_cont :: SimplCont
sc_cont = Kind -> SimplCont
mkBoringStop (SimplCont -> Kind
contResultType SimplCont
cont) } ) }
mkDupableStrictBind :: SimplEnv -> OutId -> OutExpr -> OutType
                    -> SimplM (SimplFloats, SimplCont)
mkDupableStrictBind :: SimplEnv
-> OutId -> CoreExpr -> Kind -> SimplM (SimplFloats, SimplCont)
mkDupableStrictBind SimplEnv
env OutId
arg_bndr CoreExpr
join_rhs Kind
res_ty
  | CoreExpr -> Bool
exprIsTrivial CoreExpr
join_rhs   
  = (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env
           , StrictBind { sc_bndr :: OutId
sc_bndr = OutId
arg_bndr, sc_bndrs :: [OutId]
sc_bndrs = []
                        , sc_body :: CoreExpr
sc_body = CoreExpr
join_rhs
                        , sc_env :: SimplEnv
sc_env  = SimplEnv -> SimplEnv
zapSubstEnv SimplEnv
env
                          
                        , sc_dup :: DupFlag
sc_dup  = DupFlag
OkToDup
                        , sc_cont :: SimplCont
sc_cont = Kind -> SimplCont
mkBoringStop Kind
res_ty } )
  | Bool
otherwise
  = do { OutId
join_bndr <- [OutId] -> Kind -> SimplM OutId
newJoinId [OutId
arg_bndr] Kind
res_ty
       ; let arg_info :: ArgInfo
arg_info = ArgInfo { ai_fun :: OutId
ai_fun   = OutId
join_bndr
                                , ai_rules :: FunRules
ai_rules = FunRules
forall a. Maybe a
Nothing, ai_args :: [ArgSpec]
ai_args  = []
                                , ai_encl :: Bool
ai_encl  = Bool
False, ai_dmds :: [Demand]
ai_dmds  = Demand -> [Demand]
forall a. a -> [a]
repeat Demand
topDmd
                                , ai_discs :: [Int]
ai_discs = Int -> [Int]
forall a. a -> [a]
repeat Int
0 }
       ; (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return ( SimplFloats -> JoinFloats -> SimplFloats
addJoinFloats (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env) (JoinFloats -> SimplFloats) -> JoinFloats -> SimplFloats
forall a b. (a -> b) -> a -> b
$
                  InBind -> JoinFloats
unitJoinFloat                   (InBind -> JoinFloats) -> InBind -> JoinFloats
forall a b. (a -> b) -> a -> b
$
                  OutId -> CoreExpr -> InBind
forall b. b -> Expr b -> Bind b
NonRec OutId
join_bndr                (CoreExpr -> InBind) -> CoreExpr -> InBind
forall a b. (a -> b) -> a -> b
$
                  OutId -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam (OutId -> OutId
setOneShotLambda OutId
arg_bndr) CoreExpr
join_rhs
                , StrictArg { sc_dup :: DupFlag
sc_dup    = DupFlag
OkToDup
                            , sc_fun :: ArgInfo
sc_fun    = ArgInfo
arg_info
                            , sc_fun_ty :: Kind
sc_fun_ty = OutId -> Kind
idType OutId
join_bndr
                            , sc_cont :: SimplCont
sc_cont   = Kind -> SimplCont
mkBoringStop Kind
res_ty
                            } ) }
mkDupableAlt :: Platform -> OutId
             -> JoinFloats -> OutAlt
             -> SimplM (JoinFloats, OutAlt)
mkDupableAlt :: Platform
-> OutId
-> JoinFloats
-> Alt OutId
-> SimplM (JoinFloats, Alt OutId)
mkDupableAlt Platform
_platform OutId
case_bndr JoinFloats
jfloats (Alt AltCon
con [OutId]
bndrs' CoreExpr
rhs')
  | CoreExpr -> Bool
exprIsTrivial CoreExpr
rhs'   
  = (JoinFloats, Alt OutId) -> SimplM (JoinFloats, Alt OutId)
forall (m :: * -> *) a. Monad m => a -> m a
return (JoinFloats
jfloats, AltCon -> [OutId] -> CoreExpr -> Alt OutId
forall b. AltCon -> [b] -> Expr b -> Alt b
Alt AltCon
con [OutId]
bndrs' CoreExpr
rhs')
  | Bool
otherwise
  = do  { SimpleOpts
simpl_opts <- DynFlags -> SimpleOpts
initSimpleOpts (DynFlags -> SimpleOpts) -> SimplM DynFlags -> SimplM SimpleOpts
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SimplM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
        ; let rhs_ty' :: Kind
rhs_ty'  = CoreExpr -> Kind
exprType CoreExpr
rhs'
              scrut_ty :: Kind
scrut_ty = OutId -> Kind
idType OutId
case_bndr
              case_bndr_w_unf :: OutId
case_bndr_w_unf
                = case AltCon
con of
                      AltCon
DEFAULT    -> OutId
case_bndr
                      DataAlt DataCon
dc -> OutId -> Unfolding -> OutId
setIdUnfolding OutId
case_bndr Unfolding
unf
                          where
                                 
                             unf :: Unfolding
unf = SimpleOpts -> CoreExpr -> Unfolding
mkInlineUnfolding SimpleOpts
simpl_opts CoreExpr
rhs
                             rhs :: CoreExpr
rhs = DataCon -> [Kind] -> [OutId] -> CoreExpr
forall b. DataCon -> [Kind] -> [OutId] -> Expr b
mkConApp2 DataCon
dc (Kind -> [Kind]
tyConAppArgs Kind
scrut_ty) [OutId]
bndrs'
                      LitAlt {} -> WARN( True, text "mkDupableAlt"
                                                <+> ppr case_bndr <+> ppr con )
                                   OutId
case_bndr
                           
                           
              final_bndrs' :: [OutId]
final_bndrs'
                | OutId -> Bool
isDeadBinder OutId
case_bndr = (OutId -> Bool) -> [OutId] -> [OutId]
forall a. (a -> Bool) -> [a] -> [a]
filter OutId -> Bool
abstract_over [OutId]
bndrs'
                | Bool
otherwise              = [OutId]
bndrs' [OutId] -> [OutId] -> [OutId]
forall a. [a] -> [a] -> [a]
++ [OutId
case_bndr_w_unf]
              abstract_over :: OutId -> Bool
abstract_over OutId
bndr
                  | OutId -> Bool
isTyVar OutId
bndr = Bool
True 
                  | Bool
otherwise    = Bool -> Bool
not (OutId -> Bool
isDeadBinder OutId
bndr)
                        
              final_args :: [CoreExpr]
final_args = [OutId] -> [CoreExpr]
forall b. [OutId] -> [Expr b]
varsToCoreExprs [OutId]
final_bndrs'
                           
                
                
                
                
              really_final_bndrs :: [OutId]
really_final_bndrs     = (OutId -> OutId) -> [OutId] -> [OutId]
forall a b. (a -> b) -> [a] -> [b]
map OutId -> OutId
one_shot [OutId]
final_bndrs'
              one_shot :: OutId -> OutId
one_shot OutId
v | OutId -> Bool
isId OutId
v    = OutId -> OutId
setOneShotLambda OutId
v
                         | Bool
otherwise = OutId
v
              join_rhs :: CoreExpr
join_rhs   = [OutId] -> CoreExpr -> CoreExpr
forall b. [b] -> Expr b -> Expr b
mkLams [OutId]
really_final_bndrs CoreExpr
rhs'
        ; OutId
join_bndr <- [OutId] -> Kind -> SimplM OutId
newJoinId [OutId]
final_bndrs' Kind
rhs_ty'
        ; let join_call :: CoreExpr
join_call = CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps (OutId -> CoreExpr
forall b. OutId -> Expr b
Var OutId
join_bndr) [CoreExpr]
final_args
              alt' :: Alt OutId
alt'      = AltCon -> [OutId] -> CoreExpr -> Alt OutId
forall b. AltCon -> [b] -> Expr b -> Alt b
Alt AltCon
con [OutId]
bndrs' CoreExpr
join_call
        ; (JoinFloats, Alt OutId) -> SimplM (JoinFloats, Alt OutId)
forall (m :: * -> *) a. Monad m => a -> m a
return ( JoinFloats
jfloats JoinFloats -> JoinFloats -> JoinFloats
`addJoinFlts` InBind -> JoinFloats
unitJoinFloat (OutId -> CoreExpr -> InBind
forall b. b -> Expr b -> Bind b
NonRec OutId
join_bndr CoreExpr
join_rhs)
                 , Alt OutId
alt') }
                
simplLetUnfolding :: SimplEnv-> TopLevelFlag
                  -> MaybeJoinCont
                  -> InId
                  -> OutExpr -> OutType -> ArityType
                  -> Unfolding -> SimplM Unfolding
simplLetUnfolding :: SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> OutId
-> CoreExpr
-> Kind
-> ArityType
-> Unfolding
-> SimplM Unfolding
simplLetUnfolding SimplEnv
env TopLevelFlag
top_lvl MaybeJoinCont
cont_mb OutId
id CoreExpr
new_rhs Kind
rhs_ty ArityType
arity Unfolding
unf
  | Unfolding -> Bool
isStableUnfolding Unfolding
unf
  = SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> OutId
-> Kind
-> ArityType
-> Unfolding
-> SimplM Unfolding
simplStableUnfolding SimplEnv
env TopLevelFlag
top_lvl MaybeJoinCont
cont_mb OutId
id Kind
rhs_ty ArityType
arity Unfolding
unf
  | OutId -> Bool
isExitJoinId OutId
id
  = Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return Unfolding
noUnfolding 
  | Bool
otherwise
  = 
    let !opts :: UnfoldingOpts
opts = SimplEnv -> UnfoldingOpts
seUnfoldingOpts SimplEnv
env
    in UnfoldingOpts
-> TopLevelFlag
-> UnfoldingSource
-> OutId
-> CoreExpr
-> SimplM Unfolding
mkLetUnfolding UnfoldingOpts
opts TopLevelFlag
top_lvl UnfoldingSource
InlineRhs OutId
id CoreExpr
new_rhs
mkLetUnfolding :: UnfoldingOpts -> TopLevelFlag -> UnfoldingSource
               -> InId -> OutExpr -> SimplM Unfolding
mkLetUnfolding :: UnfoldingOpts
-> TopLevelFlag
-> UnfoldingSource
-> OutId
-> CoreExpr
-> SimplM Unfolding
mkLetUnfolding !UnfoldingOpts
uf_opts TopLevelFlag
top_lvl UnfoldingSource
src OutId
id CoreExpr
new_rhs
  = Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return (UnfoldingOpts
-> UnfoldingSource -> Bool -> Bool -> CoreExpr -> Unfolding
mkUnfolding UnfoldingOpts
uf_opts UnfoldingSource
src Bool
is_top_lvl Bool
is_bottoming CoreExpr
new_rhs)
            
            
            
            
            
            
  where
    
    
    !is_top_lvl :: Bool
is_top_lvl   = TopLevelFlag -> Bool
isTopLevel TopLevelFlag
top_lvl
    
    !is_bottoming :: Bool
is_bottoming = OutId -> Bool
isDeadEndId OutId
id
simplStableUnfolding :: SimplEnv -> TopLevelFlag
                     -> MaybeJoinCont  
                     -> InId
                     -> OutType
                     -> ArityType      
                     -> Unfolding
                     ->SimplM Unfolding
simplStableUnfolding :: SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> OutId
-> Kind
-> ArityType
-> Unfolding
-> SimplM Unfolding
simplStableUnfolding SimplEnv
env TopLevelFlag
top_lvl MaybeJoinCont
mb_cont OutId
id Kind
rhs_ty ArityType
id_arity Unfolding
unf
  = case Unfolding
unf of
      Unfolding
NoUnfolding   -> Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return Unfolding
unf
      Unfolding
BootUnfolding -> Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return Unfolding
unf
      OtherCon {}   -> Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return Unfolding
unf
      DFunUnfolding { df_bndrs :: Unfolding -> [OutId]
df_bndrs = [OutId]
bndrs, df_con :: Unfolding -> DataCon
df_con = DataCon
con, df_args :: Unfolding -> [CoreExpr]
df_args = [CoreExpr]
args }
        -> do { (SimplEnv
env', [OutId]
bndrs') <- SimplEnv -> [OutId] -> SimplM (SimplEnv, [OutId])
simplBinders SimplEnv
unf_env [OutId]
bndrs
              ; [CoreExpr]
args' <- (CoreExpr -> SimplM CoreExpr) -> [CoreExpr] -> SimplM [CoreExpr]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr SimplEnv
env') [CoreExpr]
args
              ; Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return ([OutId] -> DataCon -> [CoreExpr] -> Unfolding
mkDFunUnfolding [OutId]
bndrs' DataCon
con [CoreExpr]
args') }
      CoreUnfolding { uf_tmpl :: Unfolding -> CoreExpr
uf_tmpl = CoreExpr
expr, uf_src :: Unfolding -> UnfoldingSource
uf_src = UnfoldingSource
src, uf_guidance :: Unfolding -> UnfoldingGuidance
uf_guidance = UnfoldingGuidance
guide }
        | UnfoldingSource -> Bool
isStableSource UnfoldingSource
src
        -> do { CoreExpr
expr' <- case MaybeJoinCont
mb_cont of
                           Just SimplCont
cont -> 
                                        
                                        SimplEnv -> OutId -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplJoinRhs SimplEnv
unf_env OutId
id CoreExpr
expr SimplCont
cont
                           MaybeJoinCont
Nothing   -> 
                                        do { CoreExpr
expr' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
unf_env CoreExpr
expr (Kind -> SimplCont
mkBoringStop Kind
rhs_ty)
                                           ; CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> CoreExpr
eta_expand CoreExpr
expr') }
              ; case UnfoldingGuidance
guide of
                  UnfWhen { ug_arity :: UnfoldingGuidance -> Int
ug_arity = Int
arity
                          , ug_unsat_ok :: UnfoldingGuidance -> Bool
ug_unsat_ok = Bool
sat_ok
                          , ug_boring_ok :: UnfoldingGuidance -> Bool
ug_boring_ok = Bool
boring_ok
                          }
                          
                        
                        
                        
                        
                        
                     -> let !new_boring_ok :: Bool
new_boring_ok = Bool
boring_ok Bool -> Bool -> Bool
|| CoreExpr -> Bool
inlineBoringOk CoreExpr
expr'
                            guide' :: UnfoldingGuidance
guide' =
                              UnfWhen { ug_arity :: Int
ug_arity = Int
arity
                                      , ug_unsat_ok :: Bool
ug_unsat_ok = Bool
sat_ok
                                      , ug_boring_ok :: Bool
ug_boring_ok = Bool
new_boring_ok
                                      }
                        
                        
                        
                        
                        
                        
                        
                        in Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return (UnfoldingSource
-> Bool -> CoreExpr -> UnfoldingGuidance -> Unfolding
mkCoreUnfolding UnfoldingSource
src Bool
is_top_lvl CoreExpr
expr' UnfoldingGuidance
guide')
                            
                  UnfoldingGuidance
_other              
                     -> UnfoldingOpts
-> TopLevelFlag
-> UnfoldingSource
-> OutId
-> CoreExpr
-> SimplM Unfolding
mkLetUnfolding UnfoldingOpts
uf_opts TopLevelFlag
top_lvl UnfoldingSource
src OutId
id CoreExpr
expr' }
                
                
                
        | Bool
otherwise -> Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return Unfolding
noUnfolding   
  where
    uf_opts :: UnfoldingOpts
uf_opts    = SimplEnv -> UnfoldingOpts
seUnfoldingOpts SimplEnv
env
    
    
    !is_top_lvl :: Bool
is_top_lvl = TopLevelFlag -> Bool
isTopLevel TopLevelFlag
top_lvl
    act :: Activation
act        = OutId -> Activation
idInlineActivation OutId
id
    unf_env :: SimplEnv
unf_env    = (SimplMode -> SimplMode) -> SimplEnv -> SimplEnv
updMode (Activation -> SimplMode -> SimplMode
updModeForStableUnfoldings Activation
act) SimplEnv
env
         
    
    eta_expand :: CoreExpr -> CoreExpr
eta_expand CoreExpr
expr
      | Bool -> Bool
not Bool
eta_on         = CoreExpr
expr
      | CoreExpr -> Bool
exprIsTrivial CoreExpr
expr = CoreExpr
expr
      | Bool
otherwise          = ArityType -> CoreExpr -> CoreExpr
etaExpandAT ArityType
id_arity CoreExpr
expr
    eta_on :: Bool
eta_on = SimplMode -> Bool
sm_eta_expand (SimplEnv -> SimplMode
getMode SimplEnv
env)
addBndrRules :: SimplEnv -> InBndr -> OutBndr
             -> MaybeJoinCont   
                                
             -> SimplM (SimplEnv, OutBndr)
addBndrRules :: SimplEnv
-> OutId -> OutId -> MaybeJoinCont -> SimplM (SimplEnv, OutId)
addBndrRules SimplEnv
env OutId
in_id OutId
out_id MaybeJoinCont
mb_cont
  | [CoreRule] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CoreRule]
old_rules
  = (SimplEnv, OutId) -> SimplM (SimplEnv, OutId)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv
env, OutId
out_id)
  | Bool
otherwise
  = do { [CoreRule]
new_rules <- SimplEnv
-> Maybe OutId -> [CoreRule] -> MaybeJoinCont -> SimplM [CoreRule]
simplRules SimplEnv
env (OutId -> Maybe OutId
forall a. a -> Maybe a
Just OutId
out_id) [CoreRule]
old_rules MaybeJoinCont
mb_cont
       ; let final_id :: OutId
final_id  = OutId
out_id OutId -> RuleInfo -> OutId
`setIdSpecialisation` [CoreRule] -> RuleInfo
mkRuleInfo [CoreRule]
new_rules
       ; (SimplEnv, OutId) -> SimplM (SimplEnv, OutId)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> OutId -> SimplEnv
modifyInScope SimplEnv
env OutId
final_id, OutId
final_id) }
  where
    old_rules :: [CoreRule]
old_rules = RuleInfo -> [CoreRule]
ruleInfoRules (OutId -> RuleInfo
idSpecialisation OutId
in_id)
simplRules :: SimplEnv -> Maybe OutId -> [CoreRule]
           -> MaybeJoinCont -> SimplM [CoreRule]
simplRules :: SimplEnv
-> Maybe OutId -> [CoreRule] -> MaybeJoinCont -> SimplM [CoreRule]
simplRules SimplEnv
env Maybe OutId
mb_new_id [CoreRule]
rules MaybeJoinCont
mb_cont
  = (CoreRule -> SimplM CoreRule) -> [CoreRule] -> SimplM [CoreRule]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM CoreRule -> SimplM CoreRule
simpl_rule [CoreRule]
rules
  where
    simpl_rule :: CoreRule -> SimplM CoreRule
simpl_rule rule :: CoreRule
rule@(BuiltinRule {})
      = CoreRule -> SimplM CoreRule
forall (m :: * -> *) a. Monad m => a -> m a
return CoreRule
rule
    simpl_rule rule :: CoreRule
rule@(Rule { ru_bndrs :: CoreRule -> [OutId]
ru_bndrs = [OutId]
bndrs, ru_args :: CoreRule -> [CoreExpr]
ru_args = [CoreExpr]
args
                          , ru_fn :: CoreRule -> Name
ru_fn = Name
fn_name, ru_rhs :: CoreRule -> CoreExpr
ru_rhs = CoreExpr
rhs
                          , ru_act :: CoreRule -> Activation
ru_act = Activation
act })
      = do { (SimplEnv
env', [OutId]
bndrs') <- SimplEnv -> [OutId] -> SimplM (SimplEnv, [OutId])
simplBinders SimplEnv
env [OutId]
bndrs
           ; let rhs_ty :: Kind
rhs_ty = SimplEnv -> Kind -> Kind
substTy SimplEnv
env' (CoreExpr -> Kind
exprType CoreExpr
rhs)
                 rhs_cont :: SimplCont
rhs_cont = case MaybeJoinCont
mb_cont of  
                                MaybeJoinCont
Nothing   -> Kind -> SimplCont
mkBoringStop Kind
rhs_ty
                                Just SimplCont
cont -> ASSERT2( join_ok, bad_join_msg )
                                             SimplCont
cont
                 lhs_env :: SimplEnv
lhs_env = (SimplMode -> SimplMode) -> SimplEnv -> SimplEnv
updMode SimplMode -> SimplMode
updModeForRules SimplEnv
env'
                 rhs_env :: SimplEnv
rhs_env = (SimplMode -> SimplMode) -> SimplEnv -> SimplEnv
updMode (Activation -> SimplMode -> SimplMode
updModeForStableUnfoldings Activation
act) SimplEnv
env'
                           
                 fn_name' :: Name
fn_name' = case Maybe OutId
mb_new_id of
                              Just OutId
id -> OutId -> Name
idName OutId
id
                              Maybe OutId
Nothing -> Name
fn_name
                 
                 
                 
                 join_ok :: Bool
join_ok = case Maybe OutId
mb_new_id of
                             Just OutId
id | Just Int
join_arity <- OutId -> Maybe Int
isJoinId_maybe OutId
id
                                     -> [CoreExpr] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [CoreExpr]
args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
join_arity
                             Maybe OutId
_ -> Bool
False
                 bad_join_msg :: SDoc
bad_join_msg = [SDoc] -> SDoc
vcat [ Maybe OutId -> SDoc
forall a. Outputable a => a -> SDoc
ppr Maybe OutId
mb_new_id, CoreRule -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreRule
rule
                                     , Maybe (Maybe Int) -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((OutId -> Maybe Int) -> Maybe OutId -> Maybe (Maybe Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap OutId -> Maybe Int
isJoinId_maybe Maybe OutId
mb_new_id) ]
           ; [CoreExpr]
args' <- (CoreExpr -> SimplM CoreExpr) -> [CoreExpr] -> SimplM [CoreExpr]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr SimplEnv
lhs_env) [CoreExpr]
args
           ; CoreExpr
rhs'  <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
rhs_env CoreExpr
rhs SimplCont
rhs_cont
           ; CoreRule -> SimplM CoreRule
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreRule
rule { ru_bndrs :: [OutId]
ru_bndrs = [OutId]
bndrs'
                          , ru_fn :: Name
ru_fn    = Name
fn_name'
                          , ru_args :: [CoreExpr]
ru_args  = [CoreExpr]
args'
                          , ru_rhs :: CoreExpr
ru_rhs   = CoreExpr
rhs' }) }