- ; return (usg', scrut_occ, (con,bs,rhs')) }
-
-scExpr env (Let bind body)
- = scBind env bind `thenUs` \ (env', bind_usg, bind') ->
- scExpr env' body `thenUs` \ (body_usg, body') ->
- returnUs (bind_usg `combineUsage` body_usg, Let bind' body')
-
-scExpr env e@(App _ _)
+ ; return (usg', scrut_occ, (con,bs',rhs')) }
+
+scExpr' env (Let (NonRec bndr rhs) body)
+ = do { let (body_env, bndr') = extendBndr env bndr
+ ; (rhs_usg, rhs_info@(_, args', rhs_body', _)) <- scRecRhs env (bndr',rhs)
+
+ ; if null args' || isEmptyVarEnv (calls rhs_usg) then do
+ do { -- Vanilla case
+ let rhs' = mkLams args' rhs_body'
+ body_env2 = extendConEnv body_env bndr' (isConApp (sc_cons env) rhs')
+ -- Record if the RHS is a constructor
+ ; (body_usg, body') <- scExpr body_env2 body
+ ; return (body_usg `combineUsage` rhs_usg, Let (NonRec bndr' rhs') body') }
+ else
+ do { -- Join-point case
+ let body_env2 = extendHowBound body_env [bndr'] RecFun
+ -- If the RHS of this 'let' contains calls
+ -- to recursive functions that we're trying
+ -- to specialise, then treat this let too
+ -- as one to specialise
+ ; (body_usg, body') <- scExpr body_env2 body
+
+ ; (spec_usg, _, specs) <- specialise env (calls body_usg) ([], rhs_info)
+
+ ; return (body_usg { calls = calls body_usg `delVarEnv` bndr' }
+ `combineUsage` rhs_usg `combineUsage` spec_usg,
+ mkLets [NonRec b r | (b,r) <- addRules rhs_info specs] body')
+ } }
+
+scExpr' env (Let (Rec prs) body)
+ = do { (env', bind_usg, bind') <- scBind env (Rec prs)
+ ; (body_usg, body') <- scExpr env' body
+ ; return (bind_usg `combineUsage` body_usg, Let bind' body') }
+
+scExpr' env e@(App _ _)