+ ; (rhs_usgs, rhs_infos) <- mapAndUnzipM (scRecRhs rhs_env2) (bndrs' `zip` rhss)
+ ; (body_usg, body') <- scExpr rhs_env2 body
+
+ -- NB: start specLoop from body_usg
+ ; (spec_usg, specs) <- specLoop rhs_env2 (scu_calls body_usg) rhs_infos nullUsage
+ [SI [] 0 (Just usg) | usg <- rhs_usgs]
+
+ ; let all_usg = spec_usg `combineUsage` body_usg
+ bind' = Rec (concat (zipWith specInfoBinds rhs_infos specs))
+
+ ; return (all_usg { scu_calls = scu_calls all_usg `delVarEnvList` bndrs' },
+ Let bind' body') }
+
+-----------------------------------
+scApp :: ScEnv -> (InExpr, [InExpr]) -> UniqSM (ScUsage, CoreExpr)
+
+scApp env (Var fn, args) -- Function is a variable
+ = ASSERT( not (null args) )
+ do { args_w_usgs <- mapM (scExpr env) args
+ ; let (arg_usgs, args') = unzip args_w_usgs
+ arg_usg = combineUsages arg_usgs
+ ; case scSubstId env fn of
+ fn'@(Lam {}) -> scExpr (zapScSubst env) (doBeta fn' args')
+ -- Do beta-reduction and try again
+
+ Var fn' -> return (arg_usg `combineUsage` fn_usg, mkApps (Var fn') args')
+ where
+ fn_usg = case lookupHowBound env fn' of
+ Just RecFun -> SCU { scu_calls = unitVarEnv fn' [(sc_vals env, args')],
+ scu_occs = emptyVarEnv }
+ Just RecArg -> SCU { scu_calls = emptyVarEnv,
+ scu_occs = unitVarEnv fn' (ScrutOcc emptyUFM) }
+ Nothing -> nullUsage
+
+
+ other_fn' -> return (arg_usg, mkApps other_fn' args') }
+ -- NB: doing this ignores any usage info from the substituted
+ -- function, but I don't think that matters. If it does
+ -- we can fix it.
+ where
+ doBeta :: OutExpr -> [OutExpr] -> OutExpr
+ -- ToDo: adjust for System IF
+ doBeta (Lam bndr body) (arg : args) = Let (NonRec bndr arg) (doBeta body args)
+ doBeta fn args = mkApps fn args
+
+-- The function is almost always a variable, but not always.
+-- In particular, if this pass follows float-in,
+-- which it may, we can get
+-- (let f = ...f... in f) arg1 arg2
+scApp env (other_fn, args)
+ = do { (fn_usg, fn') <- scExpr env other_fn
+ ; (arg_usgs, args') <- mapAndUnzipM (scExpr env) args
+ ; return (combineUsages arg_usgs `combineUsage` fn_usg, mkApps fn' args') }