[project @ 1998-08-24 11:16:10 by sof]
[ghc-hetmet.git] / ghc / compiler / stgSyn / CoreToStg.lhs
index 1042d3c..77d01ff 100644 (file)
 Convert a @CoreSyntax@ program to a @StgSyntax@ program.
 
 \begin{code}
-#include "HsVersions.h"
-
 module CoreToStg ( topCoreBindsToStg ) where
 
-IMP_Ubiq(){-uitous-}
-IMPORT_1_3(Ratio(numerator,denominator))
+#include "HsVersions.h"
 
 import CoreSyn         -- input
 import StgSyn          -- output
 
-import Bag             ( emptyBag, unitBag, unionBags, unionManyBags, bagToList )
 import CoreUtils       ( coreExprType )
 import CostCentre      ( noCostCentre )
-import Id              ( mkSysLocal, idType, isBottomingId,
-                         externallyVisibleId,
-                         nullIdEnv, addOneToIdEnv, lookupIdEnv, growIdEnvList,
-                         SYN_IE(IdEnv), GenId{-instance NamedThing-}, SYN_IE(Id)
+import MkId            ( mkSysLocal ) 
+import Id              ( externallyVisibleId, mkIdWithNewUniq,
+                         nullIdEnv, addOneToIdEnv, lookupIdEnv,
+                         IdEnv, Id
                        )
-import Literal         ( mkMachInt, Literal(..) )
-import PrelVals                ( unpackCStringId, unpackCString2Id,
-                         integerZeroId, integerPlusOneId,
-                         integerPlusTwoId, integerMinusOneId
-                       )
-import PrimOp          ( PrimOp(..) )
-import SpecUtils       ( mkSpecialisedCon )
 import SrcLoc          ( noSrcLoc )
-import TyCon           ( TyCon{-instance Uniquable-} )
-import Type            ( maybeAppDataTyCon, getAppDataTyConExpandingDicts, SYN_IE(Type) )
-import TysWiredIn      ( stringTy )
-import Unique          ( integerTyConKey, ratioTyConKey, Unique{-instance Eq-} )
-import UniqSupply      -- all of it, really
-import Util            ( zipLazy, panic, assertPanic{-, pprTrace ToDo:rm-} )
---import Pretty--ToDo:rm
---import PprStyle--ToDo:rm
---import PprType  --ToDo:rm
---import Outputable--ToDo:rm
---import PprEnv--ToDo:rm
+import Type            ( splitAlgTyConApp, Type )
+import UniqSupply      ( UniqSupply, UniqSM, 
+                         returnUs, thenUs, initUs,
+                         mapUs, getUnique
+                       )
+import Outputable      ( panic )
 
 isLeakFreeType x y = False -- safe option; ToDo
 \end{code}
@@ -85,6 +69,11 @@ Because we're going to come across ``boring'' bindings like
 environment, so we can just replace all occurrences of \tr{x}
 with \tr{y}.
 
+March 98: We also use this environment to give all locally bound
+Names new unique ids, since the code generator assumes that binders
+are unique across a module. (Simplifier doesn't maintain this
+invariant any longer.)
+
 \begin{code}
 type StgEnv = IdEnv StgArg
 \end{code}
@@ -150,8 +139,20 @@ coreBindToStg env (NonRec binder rhs)
           where
                new_env = addOneToIdEnv env binder (StgConArg con_id)
 
-      other ->         -- Non-trivial RHS, so don't augment envt
-               returnUs ([StgNonRec binder stg_rhs], env)
+      other ->    -- Non-trivial RHS
+           mkUniqueBinder env binder   `thenUs` \ (new_env, new_binder) ->
+           returnUs ([StgNonRec new_binder stg_rhs], new_env)
+    where
+     mkUniqueBinder env binder
+       | externallyVisibleId binder = returnUs (env, binder)
+       | otherwise = 
+           -- local binder, give it a new unique Id.
+           newUniqueLocalId binder   `thenUs` \ binder' ->
+           let
+             new_env = addOneToIdEnv env binder (StgVarArg binder')
+           in
+          returnUs (new_env, binder')
+
 
 coreBindToStg env (Rec pairs)
   = -- NB: *** WE DO NOT CHECK FOR TRIV_BINDS in REC BIND ****
@@ -159,8 +160,9 @@ coreBindToStg env (Rec pairs)
     let
        (binders, rhss) = unzip pairs
     in
-    mapUs (coreRhsToStg env) rhss `thenUs` \ stg_rhss ->
-    returnUs ([StgRec (binders `zip` stg_rhss)], env)
+    newLocalIds env True{-maybe externally visible-} binders   `thenUs` \ (binders', env') ->
+    mapUs (coreRhsToStg env') rhss                             `thenUs` \ stg_rhss ->
+    returnUs ([StgRec (binders' `zip` stg_rhss)], env')
 \end{code}
 
 
@@ -210,7 +212,6 @@ coreArgsToStg env [] = ([], [])
 coreArgsToStg env (a:as)
   = case a of
        TyArg    t -> (t:trest, vrest)
-       UsageArg u -> (trest,   vrest)
        VarArg   v -> (trest,   stgLookup env v : vrest)
        LitArg   l -> (trest,   StgLitArg l     : vrest)
   where
@@ -236,9 +237,8 @@ coreExprToStg env (Var var)
 coreExprToStg env (Con con args)
   = let
        (types, stg_atoms) = coreArgsToStg env args
-       spec_con = mkSpecialisedCon con types
     in
-    returnUs (StgCon spec_con stg_atoms bOGUS_LVs)
+    returnUs (StgCon con stg_atoms bOGUS_LVs)
 
 coreExprToStg env (Prim op args)
   = let
@@ -256,9 +256,10 @@ coreExprToStg env (Prim op args)
 \begin{code}
 coreExprToStg env expr@(Lam _ _)
   = let
-       (_,_, binders, body) = collectBinders expr
+       (_, binders, body) = collectBinders expr
     in
-    coreExprToStg env body             `thenUs` \ stg_body ->
+    newLocalIds env False{-all local-} binders  `thenUs` \ (binders', env') ->
+    coreExprToStg env' body                     `thenUs` \ stg_body ->
 
     if null binders then -- it was all type/usage binders; tossed
        returnUs stg_body
@@ -270,7 +271,7 @@ coreExprToStg env expr@(Lam _ _)
                                  stgArgOcc
                                  bOGUS_FVs
                                  ReEntrant     -- binders is non-empty
-                                 binders
+                                 binders'
                                  stg_body))
           (StgApp (StgVarArg var) [] bOGUS_LVs))
 \end{code}
@@ -311,10 +312,11 @@ coreExprToStg env expr@(App _ _)
                                 (StgApp (StgVarArg fun_id) stg_args bOGUS_LVs))
   where
        -- Collect arguments, discarding type/usage applications
-    collect_args (App e   (TyArg _))    args = collect_args e   args
-    collect_args (App e   (UsageArg _)) args = collect_args e   args
-    collect_args (App fun arg)          args = collect_args fun (arg:args)
-    collect_args fun                    args = (fun, args)
+    collect_args (App e   (TyArg _))      args = collect_args e   args
+    collect_args (App fun arg)            args = collect_args fun (arg:args)
+    collect_args (Note (Coerce _ _) expr) args = collect_args expr args
+    collect_args (Note InlineCall   expr) args = collect_args expr args
+    collect_args fun                      args = (fun, args)
 \end{code}
 
 %************************************************************************
@@ -323,7 +325,40 @@ coreExprToStg env expr@(App _ _)
 %*                                                                     *
 %************************************************************************
 
+
+******* TO DO TO DO: fix what follows
+
+Special case for
+
+       case (op x1 ... xn) of
+         y -> e
+
+where the type of the case scrutinee is a multi-constuctor algebraic type.
+Then we simply compile code for
+
+       let y = op x1 ... xn
+       in
+       e
+
+In this case:
+
+       case (op x1 ... xn) of
+          C a b -> ...
+          y     -> e
+
+where the type of the case scrutinee is a multi-constuctor algebraic type.
+we just bomb out at the moment. It never happens in practice.
+
+**** END OF TO DO TO DO
+
 \begin{code}
+coreExprToStg env (Case scrut@(Prim op args) (AlgAlts alts (BindDefault binder rhs)))
+  = if not (null alts) then
+       panic "cgCase: case on PrimOp with default *and* alts\n"
+       -- For now, die if alts are non-empty
+    else
+       coreExprToStg env (Let (NonRec binder scrut) rhs)
+
 coreExprToStg env (Case discrim alts)
   = coreExprToStg env discrim          `thenUs` \ stg_discrim ->
     alts_to_stg discrim alts           `thenUs` \ stg_alts ->
@@ -337,7 +372,7 @@ coreExprToStg env (Case discrim alts)
     )
   where
     discrim_ty             = coreExprType discrim
-    (_, discrim_ty_args, _) = getAppDataTyConExpandingDicts discrim_ty
+    (_, discrim_ty_args, _) = splitAlgTyConApp discrim_ty
 
     alts_to_stg discrim (AlgAlts alts deflt)
       = default_to_stg discrim deflt           `thenUs` \ stg_deflt ->
@@ -346,9 +381,7 @@ coreExprToStg env (Case discrim alts)
       where
        boxed_alt_to_stg (con, bs, rhs)
          = coreExprToStg env rhs    `thenUs` \ stg_rhs ->
-           returnUs (spec_con, bs, [ True | b <- bs ]{-bogus use mask-}, stg_rhs)
-         where
-           spec_con = mkSpecialisedCon con discrim_ty_args
+           returnUs (con, bs, [ True | b <- bs ]{-bogus use mask-}, stg_rhs)
 
     alts_to_stg discrim (PrimAlts alts deflt)
       = default_to_stg discrim deflt           `thenUs` \ stg_deflt ->
@@ -389,13 +422,13 @@ coreExprToStg env (Let bind body)
 
 Covert core @scc@ expression directly to STG @scc@ expression.
 \begin{code}
-coreExprToStg env (SCC cc expr)
+coreExprToStg env (Note (SCC cc) expr)
   = coreExprToStg env expr   `thenUs` \ stg_expr ->
     returnUs (StgSCC (coreExprType expr) cc stg_expr)
 \end{code}
 
 \begin{code}
-coreExprToStg env (Coerce c ty expr) = coreExprToStg env expr
+coreExprToStg env (Note other_note expr) = coreExprToStg env expr
 \end{code}
 
 
@@ -424,6 +457,28 @@ newStgVar ty
 \end{code}
 
 \begin{code}
+newUniqueLocalId :: Id -> UniqSM Id
+newUniqueLocalId i =
+   getUnique                   `thenUs` \ uniq ->
+   returnUs (mkIdWithNewUniq i uniq)
+
+newLocalIds :: StgEnv -> Bool -> [Id] -> UniqSM ([Id], StgEnv)
+newLocalIds env maybe_visible [] = returnUs ([], env)
+newLocalIds env maybe_visible (i:is)
+ | maybe_visible && externallyVisibleId i = 
+     newLocalIds env maybe_visible is `thenUs` \ (is', env') ->
+     returnUs (i:is', env')
+ | otherwise             =
+     newUniqueLocalId i `thenUs` \ i' ->
+     let
+      new_env = addOneToIdEnv env i (StgVarArg i')
+     in
+     newLocalIds new_env maybe_visible is `thenUs` \ (is', env') ->
+     returnUs (i':is', env')
+\end{code}
+
+
+\begin{code}
 mkStgLets ::   [StgBinding]
            -> StgExpr  -- body of let
            -> StgExpr