[project @ 2000-12-07 08:22:53 by simonpj]
[ghc-hetmet.git] / ghc / compiler / stgSyn / StgSyn.lhs
index 1c10d34..c0d94bc 100644 (file)
@@ -32,9 +32,9 @@ module StgSyn (
        SRT(..), noSRT,
 
        pprStgBinding, pprStgBindings, pprStgBindingsWithSRTs,
-       getArgPrimRep,
-       isLitLitArg,
-       stgArity,
+       getArgPrimRep, pprStgAlts,
+       isLitLitArg, isDllConApp, isStgTypeArg,
+       stgArity, stgArgType,
        collectFinalStgBinders
 
 #ifdef DEBUG
@@ -45,12 +45,14 @@ module StgSyn (
 #include "HsVersions.h"
 
 import CostCentre      ( CostCentreStack, CostCentre )
-import Id              ( idPrimRep, Id )
-import Const           ( Con(..), DataCon, Literal,
-                         conPrimRep, isLitLitLit )
-import PrimRep         ( PrimRep(..) )
+import Id              ( Id, idName, idPrimRep, idType )
+import Name            ( isDllName )
+import Literal         ( Literal, literalType, isLitLitLit, literalPrimRep )
+import DataCon         ( DataCon, dataConName )
+import PrimOp          ( PrimOp )
 import Outputable
 import Type             ( Type )
+import TyCon            ( TyCon )
 import UniqSet         ( isEmptyUniqSet, uniqSetToList, UniqSet )
 \end{code}
 
@@ -80,15 +82,35 @@ data GenStgBinding bndr occ
 \begin{code}
 data GenStgArg occ
   = StgVarArg  occ
-  | StgConArg   Con            -- A literal or nullary data constructor
+  | StgLitArg   Literal
+  | StgTypeArg  Type           -- For when we want to preserve all type info
 \end{code}
 
 \begin{code}
-getArgPrimRep (StgVarArg  local) = idPrimRep local
-getArgPrimRep (StgConArg  con)  = conPrimRep con
-
-isLitLitArg (StgConArg (Literal x)) = isLitLitLit x
-isLitLitArg _                      = False
+getArgPrimRep (StgVarArg local) = idPrimRep local
+getArgPrimRep (StgLitArg lit)  = literalPrimRep lit
+
+isLitLitArg (StgLitArg lit) = isLitLitLit lit
+isLitLitArg _              = False
+
+isStgTypeArg (StgTypeArg _) = True
+isStgTypeArg other         = False
+
+isDllArg :: StgArg -> Bool
+       -- Does this argument refer to something in a different DLL?
+isDllArg (StgVarArg v)   = isDllName (idName v)
+isDllArg (StgLitArg lit) = isLitLitLit lit
+
+isDllConApp :: DataCon -> [StgArg] -> Bool
+       -- Does this constructor application refer to 
+       -- anything in a different DLL?
+       -- If so, we can't allocate it statically
+isDllConApp con args = isDllName (dataConName con) || any isDllArg args
+
+stgArgType :: StgArg -> Type
+       -- Very half baked becase we have lost the type arguments
+stgArgType (StgVarArg v)   = idType v
+stgArgType (StgLitArg lit) = literalType lit
 \end{code}
 
 %************************************************************************
@@ -119,31 +141,28 @@ type GenStgLiveVars occ = UniqSet occ
 data GenStgExpr bndr occ
   = StgApp
        occ             -- function
-       [GenStgArg occ] -- arguments
-
-    -- NB: a literal is: StgApp <lit-atom> [] ...
+       [GenStgArg occ] -- arguments; may be empty
 \end{code}
 
 %************************************************************************
 %*                                                                     *
-\subsubsection{@StgCon@ and @StgPrim@---saturated applications}
+\subsubsection{@StgConApp@ and @StgPrimApp@---saturated applications}
 %*                                                                     *
 %************************************************************************
 
 There are a specialised forms of application, for
 constructors, primitives, and literals.
 \begin{code}
-  | StgCon                     -- always saturated
-       Con
-       [GenStgArg occ]
-
-       Type                    -- Result type; this is needed for primops, where
-                               -- we need to know the result type so that we can
-                               -- assign result registers.
-
+  | StgLit     Literal
+  
+  | StgConApp  DataCon
+               [GenStgArg occ] -- Saturated
+
+  | StgPrimApp PrimOp
+               [GenStgArg occ] -- Saturated
+               Type            -- Result type; we need to know the result type
+                               -- so that we can assign result registers.
 \end{code}
-These forms are to do ``inline versions,'' as it were.
-An example might be: @f x = x:[]@.
 
 %************************************************************************
 %*                                                                     *
@@ -157,7 +176,7 @@ it encodes (\x -> e) as (let f = \x -> e in f)
 \begin{code}
   | StgLam
        Type            -- Type of whole lambda (useful when making a binder for it)
-       [Id]
+       [bndr]
        StgExpr         -- Body of lambda
 \end{code}
 
@@ -414,9 +433,33 @@ combineStgBinderInfo (StgBinderInfo arg1 unsat1 std_heap1 upd_heap1 fkap1)
 
 Just like in @CoreSyntax@ (except no type-world stuff).
 
+* Algebraic cases are done using
+       StgAlgAlts (Just tc) alts deflt
+
+* Polymorphic cases, or case of a function type, are done using
+       StgAlgAlts Nothing [] (StgBindDefault e)
+
+* Primitive cases are done using 
+       StgPrimAlts tc alts deflt
+
+We thought of giving polymorphic cases their own constructor,
+but we get a bit more code sharing this way
+
+The type constructor in StgAlgAlts/StgPrimAlts is guaranteed not
+to be abstract; that is, we can see its representation.  This is
+important because the code generator uses it to determine return
+conventions etc.  But it's not trivial where there's a moduule loop 
+involved, because some versions of a type constructor might not have
+all the constructors visible.  So mkStgAlgAlts (in CoreToStg) ensures
+that it gets the TyCon from the constructors or literals (which are
+guaranteed to have the Real McCoy) rather than from the scrutinee type.
+
 \begin{code}
 data GenStgCaseAlts bndr occ
-  = StgAlgAlts Type    -- so we can find out things about constructor family
+  = StgAlgAlts (Maybe TyCon)                   -- Just tc => scrutinee type is 
+                                               --            an algebraic data type
+                                               -- Nothing => scrutinee type is a type
+                                               --            variable or function type
                [(DataCon,                      -- alts: data constructor,
                  [bndr],                       -- constructor's parameters,
                  [Bool],                       -- "use mask", same length as
@@ -425,7 +468,8 @@ data GenStgCaseAlts bndr occ
                                                -- used in the ...
                  GenStgExpr bndr occ)] -- ...right-hand side.
                (GenStgCaseDefault bndr occ)
-  | StgPrimAlts        Type    -- so we can find out things about constructor family
+
+  | StgPrimAlts        TyCon
                [(Literal,                      -- alts: unboxed literal,
                  GenStgExpr bndr occ)] -- rhs.
                (GenStgCaseDefault bndr occ)
@@ -586,14 +630,15 @@ instance (Outputable bndr, Outputable bdee, Ord bdee)
 pprStgArg :: (Outputable bdee) => GenStgArg bdee -> SDoc
 
 pprStgArg (StgVarArg var) = ppr var
-pprStgArg (StgConArg con) = ppr con
+pprStgArg (StgLitArg con) = ppr con
+pprStgArg (StgTypeArg ty) = char '@' <+> ppr ty
 \end{code}
 
 \begin{code}
 pprStgExpr :: (Outputable bndr, Outputable bdee, Ord bdee)
           => GenStgExpr bndr bdee -> SDoc
 -- special case
-pprStgExpr (StgApp func []) = ppr func
+pprStgExpr (StgLit lit)     = ppr lit
 
 -- general case
 pprStgExpr (StgApp func args)
@@ -602,9 +647,12 @@ pprStgExpr (StgApp func args)
 \end{code}
 
 \begin{code}
-pprStgExpr (StgCon con args _)
+pprStgExpr (StgConApp con args)
   = hsep [ ppr con, brackets (interppSP args)]
 
+pprStgExpr (StgPrimApp op args _)
+  = hsep [ ppr op, brackets (interppSP args)]
+
 pprStgExpr (StgLam _ bndrs body)
   =sep [ char '\\' <+> ppr bndrs <+> ptext SLIT("->"),
         pprStgExpr body ]
@@ -673,31 +721,32 @@ pprStgExpr (StgCase expr lvs_whole lvs_rhss bndr srt alts)
                    ptext SLIT("]; rhs lvs: ["), interppSP (uniqSetToList lvs_rhss),
                    ptext SLIT("]; "),
                    pprMaybeSRT srt])),
-          nest 2 (ppr_alts alts),
+          nest 2 (pprStgAlts alts),
           char '}']
   where
-    ppr_default StgNoDefault = empty
-    ppr_default (StgBindDefault expr)
-      = hang (hsep [ptext SLIT("DEFAULT"), ptext SLIT("->")]) 4 (ppr expr)
+    pp_ty (StgAlgAlts  maybe_tycon _ _) = ppr maybe_tycon
+    pp_ty (StgPrimAlts tycon       _ _) = ppr tycon
 
-    pp_ty (StgAlgAlts  ty _ _) = ppr ty
-    pp_ty (StgPrimAlts ty _ _) = ppr ty
-
-    ppr_alts (StgAlgAlts ty alts deflt)
+pprStgAlts (StgAlgAlts _ alts deflt)
       = vcat [ vcat (map (ppr_bxd_alt) alts),
-                  ppr_default deflt ]
+              pprStgDefault deflt ]
       where
        ppr_bxd_alt (con, params, use_mask, expr)
          = hang (hsep [ppr con, interppSP params, ptext SLIT("->")])
                   4 ((<>) (ppr expr) semi)
 
-    ppr_alts (StgPrimAlts ty alts deflt)
+pprStgAlts (StgPrimAlts _ alts deflt)
       = vcat [ vcat (map (ppr_ubxd_alt) alts),
-                  ppr_default deflt ]
+              pprStgDefault deflt ]
       where
        ppr_ubxd_alt (lit, expr)
          = hang (hsep [ppr lit, ptext SLIT("->")])
                 4 ((<>) (ppr expr) semi)
+
+pprStgDefault StgNoDefault         = empty
+pprStgDefault (StgBindDefault expr) = hang (hsep [ptext SLIT("DEFAULT"), ptext SLIT("->")]) 
+                                        4 (ppr expr)
+
 \end{code}
 
 \begin{code}