{-# LANGUAGE CPP #-}
module WorkWrap ( wwTopBinds ) where
import GhcPrelude
import CoreSyn
import CoreUnfold ( certainlyWillInline, mkWwInlineRule, mkWorkerUnfolding )
import CoreUtils ( exprType, exprIsHNF )
import CoreFVs ( exprFreeVars )
import Var
import Id
import IdInfo
import Type
import UniqSupply
import BasicTypes
import DynFlags
import Demand
import WwLib
import Util
import Outputable
import FamInstEnv
import MonadUtils
#include "HsVersions.h"
wwTopBinds :: DynFlags -> FamInstEnvs -> UniqSupply -> CoreProgram -> CoreProgram
wwTopBinds :: DynFlags -> FamInstEnvs -> UniqSupply -> CoreProgram -> CoreProgram
wwTopBinds dflags :: DynFlags
dflags fam_envs :: FamInstEnvs
fam_envs us :: UniqSupply
us top_binds :: CoreProgram
top_binds
= UniqSupply -> UniqSM CoreProgram -> CoreProgram
forall a. UniqSupply -> UniqSM a -> a
initUs_ UniqSupply
us (UniqSM CoreProgram -> CoreProgram)
-> UniqSM CoreProgram -> CoreProgram
forall a b. (a -> b) -> a -> b
$ do
[CoreProgram]
top_binds' <- (CoreBind -> UniqSM CoreProgram)
-> CoreProgram -> UniqSM [CoreProgram]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (DynFlags -> FamInstEnvs -> CoreBind -> UniqSM CoreProgram
wwBind DynFlags
dflags FamInstEnvs
fam_envs) CoreProgram
top_binds
CoreProgram -> UniqSM CoreProgram
forall (m :: * -> *) a. Monad m => a -> m a
return ([CoreProgram] -> CoreProgram
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [CoreProgram]
top_binds')
wwBind :: DynFlags
-> FamInstEnvs
-> CoreBind
-> UniqSM [CoreBind]
wwBind :: DynFlags -> FamInstEnvs -> CoreBind -> UniqSM CoreProgram
wwBind dflags :: DynFlags
dflags fam_envs :: FamInstEnvs
fam_envs (NonRec binder :: CoreBndr
binder rhs :: Expr CoreBndr
rhs) = do
Expr CoreBndr
new_rhs <- DynFlags -> FamInstEnvs -> Expr CoreBndr -> UniqSM (Expr CoreBndr)
wwExpr DynFlags
dflags FamInstEnvs
fam_envs Expr CoreBndr
rhs
[(CoreBndr, Expr CoreBndr)]
new_pairs <- DynFlags
-> FamInstEnvs
-> RecFlag
-> CoreBndr
-> Expr CoreBndr
-> UniqSM [(CoreBndr, Expr CoreBndr)]
tryWW DynFlags
dflags FamInstEnvs
fam_envs RecFlag
NonRecursive CoreBndr
binder Expr CoreBndr
new_rhs
CoreProgram -> UniqSM CoreProgram
forall (m :: * -> *) a. Monad m => a -> m a
return [CoreBndr -> Expr CoreBndr -> CoreBind
forall b. b -> Expr b -> Bind b
NonRec CoreBndr
b Expr CoreBndr
e | (b :: CoreBndr
b,e :: Expr CoreBndr
e) <- [(CoreBndr, Expr CoreBndr)]
new_pairs]
wwBind dflags :: DynFlags
dflags fam_envs :: FamInstEnvs
fam_envs (Rec pairs :: [(CoreBndr, Expr CoreBndr)]
pairs)
= CoreBind -> CoreProgram
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreBind -> CoreProgram)
-> ([(CoreBndr, Expr CoreBndr)] -> CoreBind)
-> [(CoreBndr, Expr CoreBndr)]
-> CoreProgram
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(CoreBndr, Expr CoreBndr)] -> CoreBind
forall b. [(b, Expr b)] -> Bind b
Rec ([(CoreBndr, Expr CoreBndr)] -> CoreProgram)
-> UniqSM [(CoreBndr, Expr CoreBndr)] -> UniqSM CoreProgram
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((CoreBndr, Expr CoreBndr) -> UniqSM [(CoreBndr, Expr CoreBndr)])
-> [(CoreBndr, Expr CoreBndr)]
-> UniqSM [(CoreBndr, Expr CoreBndr)]
forall (m :: * -> *) a b. Monad m => (a -> m [b]) -> [a] -> m [b]
concatMapM (CoreBndr, Expr CoreBndr) -> UniqSM [(CoreBndr, Expr CoreBndr)]
do_one [(CoreBndr, Expr CoreBndr)]
pairs
where
do_one :: (CoreBndr, Expr CoreBndr) -> UniqSM [(CoreBndr, Expr CoreBndr)]
do_one (binder :: CoreBndr
binder, rhs :: Expr CoreBndr
rhs) = do Expr CoreBndr
new_rhs <- DynFlags -> FamInstEnvs -> Expr CoreBndr -> UniqSM (Expr CoreBndr)
wwExpr DynFlags
dflags FamInstEnvs
fam_envs Expr CoreBndr
rhs
DynFlags
-> FamInstEnvs
-> RecFlag
-> CoreBndr
-> Expr CoreBndr
-> UniqSM [(CoreBndr, Expr CoreBndr)]
tryWW DynFlags
dflags FamInstEnvs
fam_envs RecFlag
Recursive CoreBndr
binder Expr CoreBndr
new_rhs
wwExpr :: DynFlags -> FamInstEnvs -> CoreExpr -> UniqSM CoreExpr
wwExpr :: DynFlags -> FamInstEnvs -> Expr CoreBndr -> UniqSM (Expr CoreBndr)
wwExpr _ _ e :: Expr CoreBndr
e@(Type {}) = Expr CoreBndr -> UniqSM (Expr CoreBndr)
forall (m :: * -> *) a. Monad m => a -> m a
return Expr CoreBndr
e
wwExpr _ _ e :: Expr CoreBndr
e@(Coercion {}) = Expr CoreBndr -> UniqSM (Expr CoreBndr)
forall (m :: * -> *) a. Monad m => a -> m a
return Expr CoreBndr
e
wwExpr _ _ e :: Expr CoreBndr
e@(Lit {}) = Expr CoreBndr -> UniqSM (Expr CoreBndr)
forall (m :: * -> *) a. Monad m => a -> m a
return Expr CoreBndr
e
wwExpr _ _ e :: Expr CoreBndr
e@(Var {}) = Expr CoreBndr -> UniqSM (Expr CoreBndr)
forall (m :: * -> *) a. Monad m => a -> m a
return Expr CoreBndr
e
wwExpr dflags :: DynFlags
dflags fam_envs :: FamInstEnvs
fam_envs (Lam binder :: CoreBndr
binder expr :: Expr CoreBndr
expr)
= CoreBndr -> Expr CoreBndr -> Expr CoreBndr
forall b. b -> Expr b -> Expr b
Lam CoreBndr
new_binder (Expr CoreBndr -> Expr CoreBndr)
-> UniqSM (Expr CoreBndr) -> UniqSM (Expr CoreBndr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DynFlags -> FamInstEnvs -> Expr CoreBndr -> UniqSM (Expr CoreBndr)
wwExpr DynFlags
dflags FamInstEnvs
fam_envs Expr CoreBndr
expr
where new_binder :: CoreBndr
new_binder | CoreBndr -> Bool
isId CoreBndr
binder = CoreBndr -> CoreBndr
zapIdUsedOnceInfo CoreBndr
binder
| Bool
otherwise = CoreBndr
binder
wwExpr dflags :: DynFlags
dflags fam_envs :: FamInstEnvs
fam_envs (App f :: Expr CoreBndr
f a :: Expr CoreBndr
a)
= Expr CoreBndr -> Expr CoreBndr -> Expr CoreBndr
forall b. Expr b -> Expr b -> Expr b
App (Expr CoreBndr -> Expr CoreBndr -> Expr CoreBndr)
-> UniqSM (Expr CoreBndr)
-> UniqSM (Expr CoreBndr -> Expr CoreBndr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DynFlags -> FamInstEnvs -> Expr CoreBndr -> UniqSM (Expr CoreBndr)
wwExpr DynFlags
dflags FamInstEnvs
fam_envs Expr CoreBndr
f UniqSM (Expr CoreBndr -> Expr CoreBndr)
-> UniqSM (Expr CoreBndr) -> UniqSM (Expr CoreBndr)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> DynFlags -> FamInstEnvs -> Expr CoreBndr -> UniqSM (Expr CoreBndr)
wwExpr DynFlags
dflags FamInstEnvs
fam_envs Expr CoreBndr
a
wwExpr dflags :: DynFlags
dflags fam_envs :: FamInstEnvs
fam_envs (Tick note :: Tickish CoreBndr
note expr :: Expr CoreBndr
expr)
= Tickish CoreBndr -> Expr CoreBndr -> Expr CoreBndr
forall b. Tickish CoreBndr -> Expr b -> Expr b
Tick Tickish CoreBndr
note (Expr CoreBndr -> Expr CoreBndr)
-> UniqSM (Expr CoreBndr) -> UniqSM (Expr CoreBndr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DynFlags -> FamInstEnvs -> Expr CoreBndr -> UniqSM (Expr CoreBndr)
wwExpr DynFlags
dflags FamInstEnvs
fam_envs Expr CoreBndr
expr
wwExpr dflags :: DynFlags
dflags fam_envs :: FamInstEnvs
fam_envs (Cast expr :: Expr CoreBndr
expr co :: Coercion
co) = do
Expr CoreBndr
new_expr <- DynFlags -> FamInstEnvs -> Expr CoreBndr -> UniqSM (Expr CoreBndr)
wwExpr DynFlags
dflags FamInstEnvs
fam_envs Expr CoreBndr
expr
Expr CoreBndr -> UniqSM (Expr CoreBndr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Expr CoreBndr -> Coercion -> Expr CoreBndr
forall b. Expr b -> Coercion -> Expr b
Cast Expr CoreBndr
new_expr Coercion
co)
wwExpr dflags :: DynFlags
dflags fam_envs :: FamInstEnvs
fam_envs (Let bind :: CoreBind
bind expr :: Expr CoreBndr
expr)
= CoreProgram -> Expr CoreBndr -> Expr CoreBndr
forall b. [Bind b] -> Expr b -> Expr b
mkLets (CoreProgram -> Expr CoreBndr -> Expr CoreBndr)
-> UniqSM CoreProgram -> UniqSM (Expr CoreBndr -> Expr CoreBndr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DynFlags -> FamInstEnvs -> CoreBind -> UniqSM CoreProgram
wwBind DynFlags
dflags FamInstEnvs
fam_envs CoreBind
bind UniqSM (Expr CoreBndr -> Expr CoreBndr)
-> UniqSM (Expr CoreBndr) -> UniqSM (Expr CoreBndr)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> DynFlags -> FamInstEnvs -> Expr CoreBndr -> UniqSM (Expr CoreBndr)
wwExpr DynFlags
dflags FamInstEnvs
fam_envs Expr CoreBndr
expr
wwExpr dflags :: DynFlags
dflags fam_envs :: FamInstEnvs
fam_envs (Case expr :: Expr CoreBndr
expr binder :: CoreBndr
binder ty :: Type
ty alts :: [Alt CoreBndr]
alts) = do
Expr CoreBndr
new_expr <- DynFlags -> FamInstEnvs -> Expr CoreBndr -> UniqSM (Expr CoreBndr)
wwExpr DynFlags
dflags FamInstEnvs
fam_envs Expr CoreBndr
expr
[Alt CoreBndr]
new_alts <- (Alt CoreBndr -> UniqSM (Alt CoreBndr))
-> [Alt CoreBndr] -> UniqSM [Alt CoreBndr]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Alt CoreBndr -> UniqSM (Alt CoreBndr)
forall a.
(a, [CoreBndr], Expr CoreBndr)
-> UniqSM (a, [CoreBndr], Expr CoreBndr)
ww_alt [Alt CoreBndr]
alts
let new_binder :: CoreBndr
new_binder = CoreBndr -> CoreBndr
zapIdUsedOnceInfo CoreBndr
binder
Expr CoreBndr -> UniqSM (Expr CoreBndr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Expr CoreBndr
-> CoreBndr -> Type -> [Alt CoreBndr] -> Expr CoreBndr
forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
Case Expr CoreBndr
new_expr CoreBndr
new_binder Type
ty [Alt CoreBndr]
new_alts)
where
ww_alt :: (a, [CoreBndr], Expr CoreBndr)
-> UniqSM (a, [CoreBndr], Expr CoreBndr)
ww_alt (con :: a
con, binders :: [CoreBndr]
binders, rhs :: Expr CoreBndr
rhs) = do
Expr CoreBndr
new_rhs <- DynFlags -> FamInstEnvs -> Expr CoreBndr -> UniqSM (Expr CoreBndr)
wwExpr DynFlags
dflags FamInstEnvs
fam_envs Expr CoreBndr
rhs
let new_binders :: [CoreBndr]
new_binders = [ if CoreBndr -> Bool
isId CoreBndr
b then CoreBndr -> CoreBndr
zapIdUsedOnceInfo CoreBndr
b else CoreBndr
b
| CoreBndr
b <- [CoreBndr]
binders ]
(a, [CoreBndr], Expr CoreBndr)
-> UniqSM (a, [CoreBndr], Expr CoreBndr)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
con, [CoreBndr]
new_binders, Expr CoreBndr
new_rhs)
tryWW :: DynFlags
-> FamInstEnvs
-> RecFlag
-> Id
-> CoreExpr
-> UniqSM [(Id, CoreExpr)]
tryWW :: DynFlags
-> FamInstEnvs
-> RecFlag
-> CoreBndr
-> Expr CoreBndr
-> UniqSM [(CoreBndr, Expr CoreBndr)]
tryWW dflags :: DynFlags
dflags fam_envs :: FamInstEnvs
fam_envs is_rec :: RecFlag
is_rec fn_id :: CoreBndr
fn_id rhs :: Expr CoreBndr
rhs
| Just stable_unf :: Unfolding
stable_unf <- DynFlags -> IdInfo -> Maybe Unfolding
certainlyWillInline DynFlags
dflags IdInfo
fn_info
= [(CoreBndr, Expr CoreBndr)] -> UniqSM [(CoreBndr, Expr CoreBndr)]
forall (m :: * -> *) a. Monad m => a -> m a
return [ (CoreBndr
fn_id CoreBndr -> Unfolding -> CoreBndr
`setIdUnfolding` Unfolding
stable_unf, Expr CoreBndr
rhs) ]
| Bool
is_fun
= DynFlags
-> FamInstEnvs
-> CoreBndr
-> IdInfo
-> [Demand]
-> DmdResult
-> Expr CoreBndr
-> UniqSM [(CoreBndr, Expr CoreBndr)]
splitFun DynFlags
dflags FamInstEnvs
fam_envs CoreBndr
new_fn_id IdInfo
fn_info [Demand]
wrap_dmds DmdResult
res_info Expr CoreBndr
rhs
| Bool
is_thunk
= DynFlags
-> FamInstEnvs
-> RecFlag
-> CoreBndr
-> Expr CoreBndr
-> UniqSM [(CoreBndr, Expr CoreBndr)]
splitThunk DynFlags
dflags FamInstEnvs
fam_envs RecFlag
is_rec CoreBndr
new_fn_id Expr CoreBndr
rhs
| Bool
otherwise
= [(CoreBndr, Expr CoreBndr)] -> UniqSM [(CoreBndr, Expr CoreBndr)]
forall (m :: * -> *) a. Monad m => a -> m a
return [ (CoreBndr
new_fn_id, Expr CoreBndr
rhs) ]
where
fn_info :: IdInfo
fn_info = HasDebugCallStack => CoreBndr -> IdInfo
CoreBndr -> IdInfo
idInfo CoreBndr
fn_id
(wrap_dmds :: [Demand]
wrap_dmds, res_info :: DmdResult
res_info) = StrictSig -> ([Demand], DmdResult)
splitStrictSig (IdInfo -> StrictSig
strictnessInfo IdInfo
fn_info)
new_fn_id :: CoreBndr
new_fn_id = CoreBndr -> CoreBndr
zapIdUsedOnceInfo (CoreBndr -> CoreBndr
zapIdUsageEnvInfo CoreBndr
fn_id)
is_fun :: Bool
is_fun = [Demand] -> Bool
forall a. [a] -> Bool
notNull [Demand]
wrap_dmds Bool -> Bool -> Bool
|| CoreBndr -> Bool
isJoinId CoreBndr
fn_id
is_thunk :: Bool
is_thunk = Bool -> Bool
not Bool
is_fun Bool -> Bool -> Bool
&& Bool -> Bool
not (Expr CoreBndr -> Bool
exprIsHNF Expr CoreBndr
rhs) Bool -> Bool -> Bool
&& Bool -> Bool
not (CoreBndr -> Bool
isJoinId CoreBndr
fn_id)
Bool -> Bool -> Bool
&& Bool -> Bool
not (HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType (CoreBndr -> Type
idType CoreBndr
fn_id))
splitFun :: DynFlags -> FamInstEnvs -> Id -> IdInfo -> [Demand] -> DmdResult -> CoreExpr
-> UniqSM [(Id, CoreExpr)]
splitFun :: DynFlags
-> FamInstEnvs
-> CoreBndr
-> IdInfo
-> [Demand]
-> DmdResult
-> Expr CoreBndr
-> UniqSM [(CoreBndr, Expr CoreBndr)]
splitFun dflags :: DynFlags
dflags fam_envs :: FamInstEnvs
fam_envs fn_id :: CoreBndr
fn_id fn_info :: IdInfo
fn_info wrap_dmds :: [Demand]
wrap_dmds res_info :: DmdResult
res_info rhs :: Expr CoreBndr
rhs
= WARN( not (wrap_dmds `lengthIs` arity), ppr fn_id <+> (ppr arity $$ ppr wrap_dmds $$ ppr res_info) ) do
stuff <- mkWwBodies dflags fam_envs rhs_fvs fn_id wrap_dmds use_res_info
case stuff of
Just (work_demands, join_arity, wrap_fn, work_fn) -> do
work_uniq <- getUniqueM
let work_rhs = work_fn rhs
work_act = case fn_inline_spec of
NoInline -> fn_act
_ -> wrap_act
work_prag = InlinePragma { inl_src = SourceText "{-# INLINE"
, inl_inline = fn_inline_spec
, inl_sat = Nothing
, inl_act = work_act
, inl_rule = FunLike }
work_join_arity | isJoinId fn_id = Just join_arity
| otherwise = Nothing
work_id = mkWorkerId work_uniq fn_id (exprType work_rhs)
`setIdOccInfo` occInfo fn_info
`setInlinePragma` work_prag
`setIdUnfolding` mkWorkerUnfolding dflags work_fn fn_unfolding
`setIdStrictness` mkClosedStrictSig work_demands work_res_info
`setIdDemandInfo` worker_demand
`setIdArity` work_arity
`asJoinId_maybe` work_join_arity
work_arity = length work_demands
single_call = saturatedByOneShots arity (demandInfo fn_info)
worker_demand | single_call = mkWorkerDemand work_arity
| otherwise = topDmd
wrap_rhs = wrap_fn work_id
wrap_act = case fn_act of
ActiveAfter {} -> fn_act
NeverActive -> activeDuringFinal
_ -> activeAfterInitial
wrap_prag = InlinePragma { inl_src = SourceText "{-# INLINE"
, inl_inline = NoUserInline
, inl_sat = Nothing
, inl_act = wrap_act
, inl_rule = rule_match_info }
wrap_id = fn_id `setIdUnfolding` mkWwInlineRule dflags wrap_rhs arity
`setInlinePragma` wrap_prag
`setIdOccInfo` noOccInfo
return $ [(work_id, work_rhs), (wrap_id, wrap_rhs)]
Nothing -> return [(fn_id, rhs)]
where
rhs_fvs :: VarSet
rhs_fvs = Expr CoreBndr -> VarSet
exprFreeVars Expr CoreBndr
rhs
fn_inl_prag :: InlinePragma
fn_inl_prag = IdInfo -> InlinePragma
inlinePragInfo IdInfo
fn_info
fn_inline_spec :: InlineSpec
fn_inline_spec = InlinePragma -> InlineSpec
inl_inline InlinePragma
fn_inl_prag
fn_act :: Activation
fn_act = InlinePragma -> Activation
inl_act InlinePragma
fn_inl_prag
rule_match_info :: RuleMatchInfo
rule_match_info = InlinePragma -> RuleMatchInfo
inlinePragmaRuleMatchInfo InlinePragma
fn_inl_prag
fn_unfolding :: Unfolding
fn_unfolding = IdInfo -> Unfolding
unfoldingInfo IdInfo
fn_info
arity :: Int
arity = IdInfo -> Int
arityInfo IdInfo
fn_info
use_res_info :: DmdResult
use_res_info | CoreBndr -> Bool
isJoinId CoreBndr
fn_id = DmdResult
topRes
| Bool
otherwise = DmdResult
res_info
work_res_info :: DmdResult
work_res_info | CoreBndr -> Bool
isJoinId CoreBndr
fn_id = DmdResult
res_info
| Bool
otherwise
= case DmdResult -> Maybe Int
returnsCPR_maybe DmdResult
res_info of
Just _ -> DmdResult
topRes
Nothing -> DmdResult
res_info
splitThunk :: DynFlags -> FamInstEnvs -> RecFlag -> Var -> Expr Var -> UniqSM [(Var, Expr Var)]
splitThunk :: DynFlags
-> FamInstEnvs
-> RecFlag
-> CoreBndr
-> Expr CoreBndr
-> UniqSM [(CoreBndr, Expr CoreBndr)]
splitThunk dflags :: DynFlags
dflags fam_envs :: FamInstEnvs
fam_envs is_rec :: RecFlag
is_rec fn_id :: CoreBndr
fn_id rhs :: Expr CoreBndr
rhs
= ASSERT(not (isJoinId fn_id))
do { (useful :: Bool
useful,_, wrap_fn :: Expr CoreBndr -> Expr CoreBndr
wrap_fn, work_fn :: Expr CoreBndr -> Expr CoreBndr
work_fn) <- DynFlags
-> FamInstEnvs
-> Bool
-> [CoreBndr]
-> UniqSM
(Bool, [CoreBndr], Expr CoreBndr -> Expr CoreBndr,
Expr CoreBndr -> Expr CoreBndr)
mkWWstr DynFlags
dflags FamInstEnvs
fam_envs Bool
False [CoreBndr
fn_id]
; let res :: [(CoreBndr, Expr CoreBndr)]
res = [ (CoreBndr
fn_id, CoreBind -> Expr CoreBndr -> Expr CoreBndr
forall b. Bind b -> Expr b -> Expr b
Let (CoreBndr -> Expr CoreBndr -> CoreBind
forall b. b -> Expr b -> Bind b
NonRec CoreBndr
fn_id Expr CoreBndr
rhs) (Expr CoreBndr -> Expr CoreBndr
wrap_fn (Expr CoreBndr -> Expr CoreBndr
work_fn (CoreBndr -> Expr CoreBndr
forall b. CoreBndr -> Expr b
Var CoreBndr
fn_id)))) ]
; if Bool
useful then ASSERT2( isNonRec is_rec, ppr fn_id )
[(CoreBndr, Expr CoreBndr)] -> UniqSM [(CoreBndr, Expr CoreBndr)]
forall (m :: * -> *) a. Monad m => a -> m a
return [(CoreBndr, Expr CoreBndr)]
res
else [(CoreBndr, Expr CoreBndr)] -> UniqSM [(CoreBndr, Expr CoreBndr)]
forall (m :: * -> *) a. Monad m => a -> m a
return [(CoreBndr
fn_id, Expr CoreBndr
rhs)] }