interestingArg :: SimplEnv -> CoreExpr -> ArgSummary
-- See Note [Interesting arguments]
interestingArg env e = go env 0 e
  where
    -- n is # value args to which the expression is applied
    go env n (Var v)
       | SimplEnv { seIdSubst = ids, seInScope = in_scope } <- env
       = case lookupVarEnv ids v of
           Nothing                     -> go_var n (refineFromInScope in_scope v)
           Just (DoneId v')            -> go_var n (refineFromInScope in_scope v')
           Just (DoneEx e)             -> go (zapSubstEnv env)             n e
           Just (ContEx tvs cvs ids e) -> go (setSubstEnv env tvs cvs ids) n e

    go _   _ (Lit {})              = ValueArg
    go _   _ (Type _)              = TrivArg
    go _   _ (Coercion _)          = TrivArg
    go env n (App fn (Type _))     = go env n fn
    go env n (App fn (Coercion _)) = go env n fn
    go env n (App fn _)            = go env (n+1) fn
    go env n (Tick _ a)            = go env n a
    go env n (Cast e _)            = go env n e
    go env n (Lam v e)
       | isTyVar v                 = go env n     e
       | n>0                       = go env (n-1) e
       | otherwise                 = ValueArg
    go env n (Let _ e)             = case go env n e of { ValueArg -> ValueArg; _ -> NonTrivArg }
    go _ _ (Case {})               = NonTrivArg

    go_var n v
       | isConLikeId v     = ValueArg   -- Experimenting with 'conlike' rather that
                                        --    data constructors here
       | idArity v > n     = ValueArg   -- Catches (eg) primops with arity but no unfolding
       | n > 0             = NonTrivArg -- Saturated or unknown call
       | conlike_unfolding = ValueArg   -- n==0; look for an interesting unfolding
                                        -- See Note [Conlike is interesting]
       | otherwise         = TrivArg    -- n==0, no useful unfolding
       where
         conlike_unfolding = isConLikeUnfolding (idUnfolding v)

{-
************************************************************************
*                                                                      *
                  SimplifierMode
*                                                                      *
************************************************************************

The SimplifierMode controls several switches; see its definition in
CoreMonad
        sm_rules      :: Bool     -- Whether RULES are enabled
        sm_inline     :: Bool     -- Whether inlining is enabled
        sm_case_case  :: Bool     -- Whether case-of-case is enabled
        sm_eta_expand :: Bool     -- Whether eta-expansion is enabled
-}
interestingArg :: SimplEnv -> CoreExpr -> ArgSummary
interestingArg env e = go env 0 e
  where
    -- n is # value args to which the expression is applied
    go env n (Var v)
       | SimplEnv { seIdSubst = ids, seInScope = in_scope } <- env
       = case lookupVarEnv ids v of
           Nothing                     -> go_var n (refineFromInScope in_scope v)
           Just (DoneId v')            -> go_var n (refineFromInScope in_scope v')
           Just (DoneEx e)             -> go (zapSubstEnv env)             n e
           Just (ContEx tvs cvs ids e) -> go (setSubstEnv env tvs cvs ids) n e

    go _   _ (Lit {})              = ValueArg
    go _   _ (Type _)              = TrivArg
    go _   _ (Coercion _)          = TrivArg
    go env n (App fn (Type _))     = go env n fn
    go env n (App fn (Coercion _)) = go env n fn
    go env n (App fn _)            = go env (n+1) fn
    go env n (Tick _ a)            = go env n a
    go env n (Cast e _)            = go env n e
    go env n (Lam v e)
       | isTyVar v                 = go env n     e
       | n>0                       = go env (n-1) e
       | otherwise                 = ValueArg
    go env n (Let _ e)             = case go env n e of { ValueArg -> ValueArg; _ -> NonTrivArg }
    go _ _ (Case {})               = NonTrivArg

    go_var n v
       | isConLikeId v     = ValueArg   -- Experimenting with 'conlike' rather that
                                        --    data constructors here
       | idArity v > n     = ValueArg   -- Catches (eg) primops with arity but no unfolding
       | n > 0             = NonTrivArg -- Saturated or unknown call
       | conlike_unfolding = ValueArg   -- n==0; look for an interesting unfolding
                                        -- See Note [Conlike is interesting]
       | otherwise         = TrivArg    -- n==0, no useful unfolding
       where
         conlike_unfolding = isConLikeUnfolding (idUnfolding v)

{-
************************************************************************
*                                                                      *
                  SimplifierMode
*                                                                      *
************************************************************************

The SimplifierMode controls several switches; see its definition in
CoreMonad
        sm_rules      :: Bool     -- Whether RULES are enabled
        sm_inline     :: Bool     -- Whether inlining is enabled
        sm_case_case  :: Bool     -- Whether case-of-case is enabled
        sm_eta_expand :: Bool     -- Whether eta-expansion is enabled
-}
interestingArg env e = go env 0 e
  where
    -- n is # value args to which the expression is applied
    go env n (Var v)
       | SimplEnv { seIdSubst = ids, seInScope = in_scope } <- env
       = case lookupVarEnv ids v of
           Nothing                     -> go_var n (refineFromInScope in_scope v)
           Just (DoneId v')            -> go_var n (refineFromInScope in_scope v')
           Just (DoneEx e)             -> go (zapSubstEnv env)             n e
           Just (ContEx tvs cvs ids e) -> go (setSubstEnv env tvs cvs ids) n e

    go _   _ (Lit {})              = ValueArg
    go _   _ (Type _)              = TrivArg
    go _   _ (Coercion _)          = TrivArg
    go env n (App fn (Type _))     = go env n fn
    go env n (App fn (Coercion _)) = go env n fn
    go env n (App fn _)            = go env (n+1) fn
    go env n (Tick _ a)            = go env n a
    go env n (Cast e _)            = go env n e
    go env n (Lam v e)
       | isTyVar v                 = go env n     e
       | n>0                       = go env (n-1) e
       | otherwise                 = ValueArg
    go env n (Let _ e)             = case go env n e of { ValueArg -> ValueArg; _ -> NonTrivArg }
    go _ _ (Case {})               = NonTrivArg

    go_var n v
       | isConLikeId v     = ValueArg   -- Experimenting with 'conlike' rather that
                                        --    data constructors here
       | idArity v > n     = ValueArg   -- Catches (eg) primops with arity but no unfolding
       | n > 0             = NonTrivArg -- Saturated or unknown call
       | conlike_unfolding = ValueArg   -- n==0; look for an interesting unfolding
                                        -- See Note [Conlike is interesting]
       | otherwise         = TrivArg    -- n==0, no useful unfolding
       where
         conlike_unfolding = isConLikeUnfolding (idUnfolding v)

{-
************************************************************************
*                                                                      *
                  SimplifierMode
*                                                                      *
************************************************************************

The SimplifierMode controls several switches; see its definition in
CoreMonad
        sm_rules      :: Bool     -- Whether RULES are enabled
        sm_inline     :: Bool     -- Whether inlining is enabled
        sm_case_case  :: Bool     -- Whether case-of-case is enabled
        sm_eta_expand :: Bool     -- Whether eta-expansion is enabled
-}