[project @ 1998-05-08 12:29:10 by simonm]
[ghc-hetmet.git] / ghc / compiler / coreSyn / CoreSyn.lhs
index 1599273..4d1f954 100644 (file)
@@ -4,22 +4,21 @@
 \section[CoreSyn]{A data type for the Haskell compiler midsection}
 
 \begin{code}
-#include "HsVersions.h"
-
 module CoreSyn (
        GenCoreBinding(..), GenCoreExpr(..),
-       GenCoreArg(..),GenCoreBinder(..), GenCoreCaseAlts(..),
-       GenCoreCaseDefault(..),
+       GenCoreArg(..), GenCoreBinder(..), GenCoreCaseAlts(..),
+       GenCoreCaseDefault(..), CoreNote(..),
 
        bindersOf, pairsFromCoreBinds, rhssOfBind,
 
-       mkGenApp, mkValApp, mkTyApp, mkUseApp,
+       mkGenApp, mkValApp, mkTyApp, 
        mkApp, mkCon, mkPrim,
-       mkValLam, mkTyLam, mkUseLam,
+       mkValLam, mkTyLam, 
        mkLam,
-       digForLambdas,
+       collectBinders, collectValBinders, collectTyBinders,
+       isValBinder, notValBinder,
        
-       collectArgs, isValArg,
+       collectArgs, initialTyArgs, initialValArgs, isValArg, notValArg, numValArgs,
 
        mkCoLetAny, mkCoLetNoUnboxed, mkCoLetUnboxedToCase,
        mkCoLetsAny, mkCoLetsNoUnboxed, mkCoLetsUnboxedToCase,
@@ -28,42 +27,40 @@ module CoreSyn (
        rhssOfAlts,
 
        -- Common type instantiation...
-       CoreBinding(..),
-       CoreExpr(..),
-       CoreBinder(..),
-       CoreArg(..),
-       CoreCaseAlts(..),
-       CoreCaseDefault(..),
+       CoreBinding,
+       CoreExpr,
+       CoreBinder,
+       CoreArg,
+       CoreCaseAlts,
+       CoreCaseDefault,
 
        -- And not-so-common type instantiations...
-       TaggedCoreBinding(..),
-       TaggedCoreExpr(..),
-       TaggedCoreBinder(..),
-       TaggedCoreArg(..),
-       TaggedCoreCaseAlts(..),
-       TaggedCoreCaseDefault(..),
-
-       SimplifiableCoreBinding(..),
-       SimplifiableCoreExpr(..),
-       SimplifiableCoreBinder(..),
-       SimplifiableCoreArg(..),
-       SimplifiableCoreCaseAlts(..),
-       SimplifiableCoreCaseDefault(..)
-
-       -- and to make the interface self-sufficient ...
-
+       TaggedCoreBinding,
+       TaggedCoreExpr,
+       TaggedCoreBinder,
+       TaggedCoreArg,
+       TaggedCoreCaseAlts,
+       TaggedCoreCaseDefault,
+
+       SimplifiableCoreBinding,
+       SimplifiableCoreExpr,
+       SimplifiableCoreBinder,
+       SimplifiableCoreArg,
+       SimplifiableCoreCaseAlts,
+       SimplifiableCoreCaseDefault
     ) where
 
-import Ubiq{-uitous-}
+#include "HsVersions.h"
 
-import CostCentre      ( showCostCentre, CostCentre )
-import Id              ( idType )
-import Usage           ( UVar(..) )
+import CostCentre      ( CostCentre )
+import Id              ( idType, Id )
+import Type            ( isUnboxedType,GenType, Type )
+import TyVar           ( GenTyVar, TyVar )
 import Util            ( panic, assertPanic )
-
-isUnboxedDataType = panic "CoreSyn.isUnboxedDataType"
---eqId :: Id -> Id -> Bool
-eqId = panic "CoreSyn.eqId"
+import BinderInfo       ( BinderInfo )
+import BasicTypes      ( Unused )
+import Literal          ( Literal )
+import PrimOp           ( PrimOp )
 \end{code}
 
 %************************************************************************
@@ -81,19 +78,19 @@ bounder}.  Or {\em binder} and {\em var}.]
 A @GenCoreBinding@ is either a single non-recursive binding of a
 ``binder'' to an expression, or a mutually-recursive blob of same.
 \begin{code}
-data GenCoreBinding val_bdr val_occ tyvar uvar
-  = NonRec     val_bdr (GenCoreExpr val_bdr val_occ tyvar uvar)
-  | Rec                [(val_bdr, GenCoreExpr val_bdr val_occ tyvar uvar)]
+data GenCoreBinding val_bdr val_occ flexi
+  = NonRec     val_bdr (GenCoreExpr val_bdr val_occ flexi)
+  | Rec                [(val_bdr, GenCoreExpr val_bdr val_occ flexi)]
 \end{code}
 
 \begin{code}
-bindersOf :: GenCoreBinding val_bdr val_occ tyvar uvar -> [val_bdr]
+bindersOf :: GenCoreBinding val_bdr val_occ flexi -> [val_bdr]
 
 pairsFromCoreBinds ::
-  [GenCoreBinding val_bdr val_occ tyvar uvar] ->
-  [(val_bdr, GenCoreExpr val_bdr val_occ tyvar uvar)]
+  [GenCoreBinding val_bdr val_occ flexi] ->
+  [(val_bdr, GenCoreExpr val_bdr val_occ flexi)]
 
-rhssOfBind :: GenCoreBinding val_bdr val_occ tyvar uvar -> [GenCoreExpr val_bdr val_occ tyvar uvar]
+rhssOfBind :: GenCoreBinding val_bdr val_occ flexi -> [GenCoreExpr val_bdr val_occ flexi]
 
 bindersOf (NonRec binder _) = [binder]
 bindersOf (Rec pairs)       = [binder | (binder, _) <- pairs]
@@ -116,7 +113,7 @@ rhssOfBind (Rec pairs)    = [rhs | (_,rhs) <- pairs]
 (more-or-less) boiled-down second-order polymorphic lambda calculus.
 For types in the core world, we just keep using @Types@.
 \begin{code}
-data GenCoreExpr val_bdr val_occ tyvar uvar
+data GenCoreExpr val_bdr val_occ flexi
      = Var    val_occ
      | Lit    Literal  -- literal constants
 \end{code}
@@ -127,7 +124,7 @@ simplifier (and by the desugarer when it knows what it's doing).  The
 desugarer sets up constructors as applications of global @Vars@s.
 
 \begin{code}
-     | Con     Id [GenCoreArg val_occ tyvar uvar]
+     | Con     Id [GenCoreArg val_occ flexi]
                -- Saturated constructor application:
                -- The constructor is a function of the form:
                --      /\ a1 -> ... /\ am -> \ b1 -> ... \ bn ->
@@ -135,18 +132,19 @@ desugarer sets up constructors as applications of global @Vars@s.
                -- regular kind; there will be "m" Types and
                -- "n" bindees in the Con args.
 
-     | Prim    PrimOp [GenCoreArg val_occ tyvar uvar]
+     | Prim    PrimOp [GenCoreArg val_occ flexi]
                -- saturated primitive operation;
+
                -- comment on Cons applies here, too.
 \end{code}
 
 Ye olde abstraction and application operators.
 \begin{code}
-     | Lam     (GenCoreBinder val_bdr tyvar uvar)
-               (GenCoreExpr val_bdr val_occ tyvar uvar)
+     | Lam     (GenCoreBinder val_bdr flexi)
+               (GenCoreExpr   val_bdr val_occ flexi)
 
-     | App     (GenCoreExpr val_bdr val_occ tyvar uvar)
-               (GenCoreArg val_occ tyvar uvar)
+     | App     (GenCoreExpr val_bdr val_occ flexi)
+               (GenCoreArg  val_occ flexi)
 \end{code}
 
 Case expressions (\tr{case <expr> of <List of alternatives>}): there
@@ -154,8 +152,8 @@ are really two flavours masquerading here---those for scrutinising
 {\em algebraic} types and those for {\em primitive} types.  Please see
 under @GenCoreCaseAlts@.
 \begin{code}
-     | Case    (GenCoreExpr val_bdr val_occ tyvar uvar)
-               (GenCoreCaseAlts val_bdr val_occ tyvar uvar)
+     | Case    (GenCoreExpr val_bdr val_occ flexi)
+               (GenCoreCaseAlts val_bdr val_occ flexi)
 \end{code}
 
 A Core case expression \tr{case e of v -> ...} implies evaluation of
@@ -166,22 +164,41 @@ Non-recursive @Lets@ only have one binding; having more than one
 doesn't buy you much, and it is an easy way to mess up variable
 scoping.
 \begin{code}
-     | Let     (GenCoreBinding val_bdr val_occ tyvar uvar)
-               (GenCoreExpr val_bdr val_occ tyvar uvar)
+     | Let     (GenCoreBinding val_bdr val_occ flexi)
+               (GenCoreExpr val_bdr val_occ flexi)
                -- both recursive and non-.
                -- The "GenCoreBinding" records that information
 \end{code}
 
-For cost centre scc expressions we introduce a new core construct
-@SCC@ so transforming passes have to deal with it explicitly. The
-alternative of using a new PrimativeOp may result in a bad
-transformations of which we are unaware.
+A @Note@ annotates a @CoreExpr@ with useful information
+of some kind.
+\begin{code}
+     | Note    (CoreNote flexi)
+               (GenCoreExpr val_bdr val_occ flexi)
+\end{code}
+
+
+%************************************************************************
+%*                                                                     *
+\subsection{Core-notes}
+%*                                                                     *
+%************************************************************************
+
 \begin{code}
-     | SCC     CostCentre                                  -- label of scc
-               (GenCoreExpr val_bdr val_occ tyvar uvar)    -- scc expression
+data CoreNote flexi
+  = SCC 
+       CostCentre
+
+  | Coerce     
+       (GenType flexi)         -- The to-type:   type of whole coerce expression
+       (GenType flexi)         -- The from-type: type of enclosed expression
+
+  | InlineCall                 -- Instructs simplifier to inline
+                               -- the enclosed call
 \end{code}
 
 
+
 %************************************************************************
 %*                                                                     *
 \subsection{Core-constructing functions with checking}
@@ -197,15 +214,16 @@ being bound has unboxed type. We have different variants ...
                                (unboxed bindings in a letrec are still prohibited)
 
 \begin{code}
-mkCoLetAny :: GenCoreBinding val_bdr val_occ tyvar uvar
-          -> GenCoreExpr    val_bdr val_occ tyvar uvar
-          -> GenCoreExpr    val_bdr val_occ tyvar uvar
-mkCoLetsAny :: [GenCoreBinding val_bdr val_occ tyvar uvar] ->
-               GenCoreExpr val_bdr val_occ tyvar uvar ->
-               GenCoreExpr val_bdr val_occ tyvar uvar
-mkCoLetrecAny :: [(val_bdr, GenCoreExpr val_bdr val_occ tyvar uvar)]
-             -> GenCoreExpr val_bdr val_occ tyvar uvar
-             -> GenCoreExpr val_bdr val_occ tyvar uvar
+mkCoLetAny :: GenCoreBinding Id Id flexi
+          -> GenCoreExpr    Id Id flexi
+          -> GenCoreExpr    Id Id flexi
+mkCoLetsAny :: [GenCoreBinding Id Id flexi] ->
+               GenCoreExpr Id Id flexi ->
+               GenCoreExpr Id Id flexi
+
+mkCoLetrecAny :: [(val_bdr, GenCoreExpr val_bdr val_occ flexi)]
+             -> GenCoreExpr val_bdr val_occ flexi
+             -> GenCoreExpr val_bdr val_occ flexi
 
 mkCoLetrecAny []    body = body
 mkCoLetrecAny binds body = Let (Rec binds) body
@@ -213,27 +231,18 @@ mkCoLetrecAny binds body = Let (Rec binds) body
 mkCoLetsAny []    expr = expr
 mkCoLetsAny binds expr = foldr mkCoLetAny expr binds
 
-mkCoLetAny bind@(Rec binds) body = mkCoLetrecAny binds body
-mkCoLetAny bind@(NonRec binder rhs) body
-  = case body of
-      Var binder2 | binder `eqId` binder2
-        -> rhs   -- hey, I have the rhs
-      other
-        -> Let bind body
+mkCoLetAny bind@(Rec binds)         body = mkCoLetrecAny binds body
+mkCoLetAny bind@(NonRec binder rhs) body = Let bind body
 \end{code}
 
 \begin{code}
---mkCoLetNoUnboxed ::
---  GenCoreBinding val_bdr val_occ tyvar uvar ->
---  GenCoreExpr val_bdr val_occ tyvar uvar ->
---  GenCoreExpr val_bdr val_occ tyvar uvar
-
 mkCoLetNoUnboxed bind@(Rec binds) body
   = mkCoLetrecNoUnboxed binds body
+
 mkCoLetNoUnboxed bind@(NonRec binder rhs) body
-  = --ASSERT (not (isUnboxedDataType (idType binder)))
+  = --ASSERT (not (isUnboxedType (idType binder)))
     case body of
-      Var binder2 | binder `eqId` binder2
+      Var binder2 | binder == binder2
         -> rhs   -- hey, I have the rhs
       other
         -> Let bind body
@@ -241,33 +250,25 @@ mkCoLetNoUnboxed bind@(NonRec binder rhs) body
 mkCoLetsNoUnboxed []    expr = expr
 mkCoLetsNoUnboxed binds expr = foldr mkCoLetNoUnboxed expr binds
 
---mkCoLetrecNoUnboxed :: [(Id, CoreExpr)]      -- bindings
---                 -> CoreExpr         -- body
---                 -> CoreExpr                 -- result
-
 mkCoLetrecNoUnboxed []    body = body
 mkCoLetrecNoUnboxed binds body
   = ASSERT (all is_boxed_bind binds)
     Let (Rec binds) body
   where
     is_boxed_bind (binder, rhs)
-      = (not . isUnboxedDataType . idType) binder
+      = (not . isUnboxedType . idType) binder
 \end{code}
 
 \begin{code}
---mkCoLetUnboxedToCase ::
---  GenCoreBinding val_bdr val_occ tyvar uvar ->
---  GenCoreExpr val_bdr val_occ tyvar uvar ->
---  GenCoreExpr val_bdr val_occ tyvar uvar
-
 mkCoLetUnboxedToCase bind@(Rec binds) body
   = mkCoLetrecNoUnboxed binds body
+
 mkCoLetUnboxedToCase bind@(NonRec binder rhs) body
   = case body of
-      Var binder2 | binder `eqId` binder2
+      Var binder2 | binder == binder2
         -> rhs   -- hey, I have the rhs
       other
-        -> if (not (isUnboxedDataType (idType binder))) then
+        -> if (not (isUnboxedType (idType binder))) then
                Let bind body            -- boxed...
            else
                Case rhs                  -- unboxed...
@@ -301,24 +302,24 @@ Case e [ BindDefaultAlt x -> b ]
 \end{verbatim}
 
 \begin{code}
-data GenCoreCaseAlts val_bdr val_occ tyvar uvar
+data GenCoreCaseAlts val_bdr val_occ flexi
   = AlgAlts    [(Id,                           -- alts: data constructor,
                  [val_bdr],                    -- constructor's parameters,
-                 GenCoreExpr val_bdr val_occ tyvar uvar)]      -- rhs.
-               (GenCoreCaseDefault val_bdr val_occ tyvar uvar)
+                 GenCoreExpr val_bdr val_occ flexi)]   -- rhs.
+               (GenCoreCaseDefault val_bdr val_occ flexi)
 
   | PrimAlts   [(Literal,                      -- alts: unboxed literal,
-                 GenCoreExpr val_bdr val_occ tyvar uvar)]      -- rhs.
-               (GenCoreCaseDefault val_bdr val_occ tyvar uvar)
+                 GenCoreExpr val_bdr val_occ flexi)]   -- rhs.
+               (GenCoreCaseDefault val_bdr val_occ flexi)
 
 -- obvious things: if there are no alts in the list, then the default
 -- can't be NoDefault.
 
-data GenCoreCaseDefault val_bdr val_occ tyvar uvar
+data GenCoreCaseDefault val_bdr val_occ flexi
   = NoDefault                                  -- small con family: all
                                                -- constructor accounted for
   | BindDefault val_bdr                                -- form: var -> expr;
-               (GenCoreExpr val_bdr val_occ tyvar uvar)        -- "val_bdr" may or may not
+               (GenCoreExpr val_bdr val_occ flexi)     -- "val_bdr" may or may not
                                                -- be used in RHS.
 \end{code}
 
@@ -337,91 +338,67 @@ rhssOfDeflt (BindDefault _ rhs) = [rhs]
 %************************************************************************
 
 \begin{code}
-data GenCoreBinder val_bdr tyvar uvar
+data GenCoreBinder val_bdr flexi
   = ValBinder  val_bdr
-  | TyBinder   tyvar
-  | UsageBinder        uvar
+  | TyBinder   (GenTyVar flexi)
+
+isValBinder (ValBinder _) = True
+isValBinder _            = False
+
+notValBinder = not . isValBinder
 \end{code}
 
 Clump Lams together if possible.
 
 \begin{code}
 mkValLam :: [val_bdr]
-        -> GenCoreExpr val_bdr val_occ tyvar uvar
-        -> GenCoreExpr val_bdr val_occ tyvar uvar
-mkTyLam  :: [tyvar]
-        -> GenCoreExpr val_bdr val_occ tyvar uvar
-        -> GenCoreExpr val_bdr val_occ tyvar uvar
-mkUseLam :: [uvar]
-        -> GenCoreExpr val_bdr val_occ tyvar uvar
-        -> GenCoreExpr val_bdr val_occ tyvar uvar
+        -> GenCoreExpr val_bdr val_occ flexi
+        -> GenCoreExpr val_bdr val_occ flexi
+mkTyLam  :: [GenTyVar flexi]
+        -> GenCoreExpr val_bdr val_occ flexi
+        -> GenCoreExpr val_bdr val_occ flexi
 
 mkValLam binders body = foldr (Lam . ValBinder)   body binders
 mkTyLam  binders body = foldr (Lam . TyBinder)    body binders
-mkUseLam binders body = foldr (Lam . UsageBinder) body binders
 
-mkLam :: [tyvar] -> [val_bdr] -- ToDo: could add a [uvar] arg...
-        -> GenCoreExpr val_bdr val_occ tyvar uvar
-        -> GenCoreExpr val_bdr val_occ tyvar uvar
+mkLam :: [GenTyVar flexi] -> [val_bdr] -- ToDo: could add a [uvar] arg...
+        -> GenCoreExpr val_bdr val_occ flexi
+        -> GenCoreExpr val_bdr val_occ flexi
 
 mkLam tyvars valvars body
   = mkTyLam tyvars (mkValLam valvars body)
 \end{code}
 
 We often want to strip off leading lambdas before getting down to
-business.  @digForLambdas@ is your friend.
+business.  @collectBinders@ is your friend.
 
 We expect (by convention) usage-, type-, and value- lambdas in that
 order.
 
 \begin{code}
-digForLambdas ::
-  GenCoreExpr val_bdr val_occ tyvar uvar ->
-  ([uvar], [tyvar], [val_bdr], GenCoreExpr val_bdr val_occ tyvar uvar)
-
-digForLambdas (Lam (UsageBinder u) body)
-  = let
-       (uvars, tyvars, args, final_body) = digForLambdas body
-    in
-    (u:uvars, tyvars, args, final_body)
-
-digForLambdas other
-  = let
-       (tyvars, args, body) = dig_for_tyvars other
-    in
-    ([], tyvars, args, body)
+collectBinders ::
+  GenCoreExpr val_bdr val_occ flexi ->
+  ([GenTyVar flexi], [val_bdr], GenCoreExpr val_bdr val_occ flexi)
+
+collectBinders expr
+  = case collectValBinders body1 of { (vals,body) -> (tyvars, vals, body) }
+  where
+    (tyvars, body1) = collectTyBinders expr
+
+collectTyBinders expr
+  = tyvars expr []
   where
-    dig_for_tyvars (Lam (TyBinder tv) body)
-      = let
-           (tyvars, args, body2) = dig_for_tyvars body
-       in
-       (tv : tyvars, args, body2)
-
-    dig_for_tyvars body
-      = ASSERT(not (usage_lambda body))
-       let
-           (args, body2) = dig_for_valvars body
-       in
-       ([], args, body2)
-
-    ---------------------------------------
-    dig_for_valvars (Lam (ValBinder v) body)
-      = let
-           (args, body2) = dig_for_valvars body
-       in
-       (v : args, body2)
-
-    dig_for_valvars body
-      = ASSERT(not (usage_lambda body))
-       ASSERT(not (tyvar_lambda body))
-       ([], body)
-
-    ---------------------------------------
-    usage_lambda (Lam (UsageBinder _) _) = True
-    usage_lambda _                      = False
-
-    tyvar_lambda (Lam (TyBinder _) _)    = True
-    tyvar_lambda _                      = False
+    tyvars (Lam (TyBinder t) body) tacc = tyvars body (t:tacc)
+    tyvars other tacc = (reverse tacc, other)
+
+collectValBinders :: GenCoreExpr val_bdr val_occ flexi ->
+                    ([val_bdr], GenCoreExpr val_bdr val_occ flexi)
+collectValBinders expr
+  = go [] expr
+  where
+    go acc (Lam (ValBinder v) b) = go (v:acc) b
+    go acc body                 = (reverse acc, body)
+
 \end{code}
 
 %************************************************************************
@@ -431,31 +408,26 @@ digForLambdas other
 %************************************************************************
 
 \begin{code}
-data GenCoreArg val_occ tyvar uvar
+data GenCoreArg val_occ flexi
   = LitArg     Literal
   | VarArg     val_occ
-  | TyArg      (GenType tyvar uvar)
-  | UsageArg   (GenUsage uvar)
+  | TyArg      (GenType flexi)
 \end{code}
 
 General and specific forms:
 \begin{code}
-mkGenApp :: GenCoreExpr val_bdr val_occ tyvar uvar
-        -> [GenCoreArg val_occ tyvar uvar]
-        -> GenCoreExpr val_bdr val_occ tyvar uvar
-mkTyApp  :: GenCoreExpr val_bdr val_occ tyvar uvar
-        -> [GenType tyvar uvar]
-        -> GenCoreExpr val_bdr val_occ tyvar uvar
-mkUseApp :: GenCoreExpr val_bdr val_occ tyvar uvar
-        -> [GenUsage uvar]
-        -> GenCoreExpr val_bdr val_occ tyvar uvar
-mkValApp :: GenCoreExpr val_bdr val_occ tyvar uvar
-        -> [GenCoreArg val_occ tyvar uvar] -- but we ASSERT they are LitArg or VarArg
-        -> GenCoreExpr val_bdr val_occ tyvar uvar
+mkGenApp :: GenCoreExpr val_bdr val_occ flexi
+        -> [GenCoreArg val_occ flexi]
+        -> GenCoreExpr val_bdr val_occ flexi
+mkTyApp  :: GenCoreExpr val_bdr val_occ flexi
+        -> [GenType flexi]
+        -> GenCoreExpr val_bdr val_occ flexi
+mkValApp :: GenCoreExpr val_bdr val_occ flexi
+        -> [GenCoreArg val_occ flexi] -- but we ASSERT they are LitArg or VarArg
+        -> GenCoreExpr val_bdr val_occ flexi
 
 mkGenApp f args = foldl App                               f args
 mkTyApp  f args = foldl (\ e a -> App e (TyArg a))        f args
-mkUseApp f args = foldl (\ e a -> App e (UsageArg a))     f args
 mkValApp f args = foldl (\ e a -> App e (is_Lit_or_Var a)) f args
 
 #ifndef DEBUG
@@ -468,6 +440,10 @@ is_Lit_or_Var a
 isValArg (LitArg _) = True  -- often used for sanity-checking
 isValArg (VarArg _) = True
 isValArg _         = False
+
+notValArg = not . isValArg -- exists only because it's a common use of isValArg
+
+numValArgs as = length [ a | a <- as, isValArg a ] -- again, convenience
 \end{code}
 
 \begin{code}
@@ -475,25 +451,51 @@ mkApp  fun = mk_thing (mkGenApp fun)
 mkCon  con = mk_thing (Con      con)
 mkPrim op  = mk_thing (Prim     op)
 
-mk_thing thing uses tys vals
-  = thing (map UsageArg uses ++ map TyArg tys ++ map is_Lit_or_Var vals)
+mk_thing :: ([GenCoreArg val_occ flexi] -> GenCoreExpr val_bdr val_occ flexi)
+        -> [GenType flexi] 
+        -> [GenCoreArg val_occ flexi] 
+        -> GenCoreExpr val_bdr val_occ flexi
+mk_thing thing tys vals
+  = ASSERT( all isValArg vals )
+    thing (map TyArg tys ++ vals)
 \end{code}
 
 @collectArgs@ takes an application expression, returning the function
 and the arguments to which it is applied.
 
 \begin{code}
-collectArgs :: GenCoreExpr val_bdr val_occ tyvar uvar
-           -> (GenCoreExpr val_bdr val_occ tyvar uvar,
-               [GenCoreArg val_occ tyvar uvar])
+collectArgs :: GenCoreExpr val_bdr val_occ flexi
+           -> (GenCoreExpr val_bdr val_occ flexi,
+               [GenType flexi],
+               [GenCoreArg val_occ flexi]{-ValArgs-})
 
 collectArgs expr
-  = collect expr []
+  = valvars expr []
   where
-    collect (App fun arg) args = collect fun (arg : args)
-    collect fun                  args = (fun, args)
+    valvars (App fun v) vacc | isValArg v = valvars fun (v:vacc)
+    valvars fun vacc
+      = case (tyvars fun []) of { (expr, tacc) ->
+       (expr, tacc, vacc) }
+
+    tyvars (App fun (TyArg t)) tacc = tyvars fun (t:tacc)
+    tyvars fun tacc                = (expr, tacc)
 \end{code}
 
+
+\begin{code}
+initialTyArgs :: [GenCoreArg val_occ flexi]
+             -> ([GenType flexi], [GenCoreArg val_occ flexi])
+initialTyArgs (TyArg ty : args) = (ty:tys, args') 
+                               where
+                                 (tys, args') = initialTyArgs args
+initialTyArgs other            = ([],other)
+
+initialValArgs :: [GenCoreArg val_occ flexi]
+             -> ([GenCoreArg val_occ flexi], [GenCoreArg val_occ flexi])
+initialValArgs args = span isValArg args
+\end{code}
+
+
 %************************************************************************
 %*                                                                     *
 \subsection{The main @Core*@ instantiation of the @GenCore*@ types}
@@ -501,13 +503,13 @@ collectArgs expr
 %************************************************************************
 
 \begin{code}
-type CoreBinding = GenCoreBinding  Id Id TyVar UVar
-type CoreExpr    = GenCoreExpr     Id Id TyVar UVar
-type CoreBinder         = GenCoreBinder   Id    TyVar UVar
-type CoreArg     = GenCoreArg         Id TyVar UVar
+type CoreBinding = GenCoreBinding  Id Id Unused
+type CoreExpr    = GenCoreExpr     Id Id Unused
+type CoreBinder         = GenCoreBinder   Id    Unused
+type CoreArg     = GenCoreArg         Id Unused
 
-type CoreCaseAlts    = GenCoreCaseAlts    Id Id TyVar UVar
-type CoreCaseDefault = GenCoreCaseDefault Id Id TyVar UVar
+type CoreCaseAlts    = GenCoreCaseAlts    Id Id Unused
+type CoreCaseDefault = GenCoreCaseDefault Id Id Unused
 \end{code}
 
 %************************************************************************
@@ -520,13 +522,13 @@ Binders are ``tagged'' with a \tr{t}:
 \begin{code}
 type Tagged t = (Id, t)
 
-type TaggedCoreBinding t = GenCoreBinding (Tagged t) Id TyVar UVar
-type TaggedCoreExpr    t = GenCoreExpr    (Tagged t) Id TyVar UVar
-type TaggedCoreBinder  t = GenCoreBinder  (Tagged t)    TyVar UVar
-type TaggedCoreArg     t = GenCoreArg                Id TyVar UVar
+type TaggedCoreBinding t = GenCoreBinding (Tagged t) Id Unused
+type TaggedCoreExpr    t = GenCoreExpr    (Tagged t) Id Unused
+type TaggedCoreBinder  t = GenCoreBinder  (Tagged t)    Unused
+type TaggedCoreArg     t = GenCoreArg                Id Unused
 
-type TaggedCoreCaseAlts    t = GenCoreCaseAlts    (Tagged t) Id TyVar UVar
-type TaggedCoreCaseDefault t = GenCoreCaseDefault (Tagged t) Id TyVar UVar
+type TaggedCoreCaseAlts    t = GenCoreCaseAlts    (Tagged t) Id Unused
+type TaggedCoreCaseDefault t = GenCoreCaseDefault (Tagged t) Id Unused
 \end{code}
 
 %************************************************************************
@@ -539,11 +541,11 @@ Binders are tagged with @BinderInfo@:
 \begin{code}
 type Simplifiable = (Id, BinderInfo)
 
-type SimplifiableCoreBinding = GenCoreBinding Simplifiable Id TyVar UVar
-type SimplifiableCoreExpr    = GenCoreExpr    Simplifiable Id TyVar UVar
-type SimplifiableCoreBinder  = GenCoreBinder  Simplifiable    TyVar UVar
-type SimplifiableCoreArg     = GenCoreArg                  Id TyVar UVar
+type SimplifiableCoreBinding = GenCoreBinding Simplifiable Id Unused
+type SimplifiableCoreExpr    = GenCoreExpr    Simplifiable Id Unused
+type SimplifiableCoreBinder  = GenCoreBinder  Simplifiable    Unused
+type SimplifiableCoreArg     = GenCoreArg                  Id Unused
 
-type SimplifiableCoreCaseAlts    = GenCoreCaseAlts    Simplifiable Id TyVar UVar
-type SimplifiableCoreCaseDefault = GenCoreCaseDefault Simplifiable Id TyVar UVar
+type SimplifiableCoreCaseAlts    = GenCoreCaseAlts    Simplifiable Id Unused
+type SimplifiableCoreCaseDefault = GenCoreCaseDefault Simplifiable Id Unused
 \end{code}