[project @ 2001-02-08 15:00:28 by simonmar]
[ghc-hetmet.git] / ghc / compiler / codeGen / CgBindery.lhs
index 8fe334e..7727c99 100644 (file)
@@ -5,14 +5,14 @@
 
 \begin{code}
 module CgBindery (
-       CgBindings, CgIdInfo(..){-dubiously concrete-},
+       CgBindings, CgIdInfo,
        StableLoc, VolatileLoc,
 
-       maybeStkLoc,
-
        stableAmodeIdInfo, heapIdInfo, newTempAmodeAndIdInfo,
        letNoEscapeIdInfo, idInfoToAmode,
 
+       addBindC, addBindsC,
+
        nukeVolatileBinds,
        nukeDeadBindings,
 
@@ -32,25 +32,24 @@ import AbsCSyn
 import CgMonad
 
 import CgUsages                ( getHpRelOffset, getSpRelOffset, getRealSp )
-import CgStackery      ( freeStackSlots, addFreeSlots )
-import CLabel          ( mkStaticClosureLabel, mkClosureLabel,
-                         mkBitmapLabel )
+import CgStackery      ( freeStackSlots )
+import CLabel          ( mkClosureLabel,
+                         mkBitmapLabel, pprCLabel )
 import ClosureInfo     ( mkLFImported, mkLFArgument, LambdaFormInfo )
 import BitSet          ( mkBS, emptyBS )
 import PrimRep         ( isFollowableRep, getPrimRepSize )
-import DataCon         ( DataCon, dataConName )
 import Id              ( Id, idPrimRep, idType )
 import Type            ( typePrimRep )
 import VarEnv
 import VarSet          ( varSetElems )
-import Const           ( Con(..), Literal )
+import Literal         ( Literal )
 import Maybes          ( catMaybes, maybeToBool )
-import Name            ( isLocallyDefined, isWiredInName, NamedThing(..) )
+import Name            ( isLocalName, NamedThing(..) )
 #ifdef DEBUG
 import PprAbsC         ( pprAmode )
 #endif
 import PrimRep          ( PrimRep(..) )
-import StgSyn          ( StgArg, StgLiveVars, GenStgArg(..) )
+import StgSyn          ( StgArg, StgLiveVars, GenStgArg(..), isStgTypeArg )
 import Unique           ( Unique, Uniquable(..) )
 import UniqSet         ( elementOfUniqSet )
 import Util            ( zipWithEqual, sortLt )
@@ -165,6 +164,63 @@ idInfoPiecesToAmode kind NoVolatileLoc NoStableLoc = panic "idInfoPiecesToAmode:
 
 %************************************************************************
 %*                                                                     *
+\subsection[CgMonad-bindery]{Monad things for fiddling with @CgBindings@}
+%*                                                                     *
+%************************************************************************
+
+There are three basic routines, for adding (@addBindC@), modifying
+(@modifyBindC@) and looking up (@lookupBindC@) bindings.
+
+A @Id@ is bound to a @(VolatileLoc, StableLoc)@ triple.
+The name should not already be bound. (nice ASSERT, eh?)
+
+\begin{code}
+addBindC :: Id -> CgIdInfo -> Code
+addBindC name stuff_to_bind info_down (MkCgState absC binds usage)
+  = MkCgState absC (extendVarEnv binds name stuff_to_bind) usage
+
+addBindsC :: [(Id, CgIdInfo)] -> Code
+addBindsC new_bindings info_down (MkCgState absC binds usage)
+  = MkCgState absC new_binds usage
+  where
+    new_binds = foldl (\ binds (name,info) -> extendVarEnv binds name info)
+                     binds
+                     new_bindings
+
+modifyBindC :: Id -> (CgIdInfo -> CgIdInfo) -> Code
+modifyBindC name mangle_fn info_down (MkCgState absC binds usage)
+  = MkCgState absC (modifyVarEnv mangle_fn binds name) usage
+
+lookupBindC :: Id -> FCode CgIdInfo
+lookupBindC name info_down@(MkCgInfoDown _ static_binds srt ticky _)
+                state@(MkCgState absC local_binds usage)
+  = (val, state)
+  where
+    val = case (lookupVarEnv local_binds name) of
+           Nothing     -> try_static
+           Just this   -> this
+
+    try_static = 
+      case (lookupVarEnv static_binds name) of
+       Just this -> this
+       Nothing
+         -> cgPanic (text "lookupBindC: no info for" <+> ppr name) info_down state
+
+cgPanic :: SDoc -> CgInfoDownwards -> CgState -> a
+cgPanic doc info_down@(MkCgInfoDown _ static_binds srt ticky _)
+           state@(MkCgState absC local_binds usage)
+  = pprPanic "cgPanic"
+            (vcat [doc,
+               ptext SLIT("static binds for:"),
+               vcat [ ppr i | (MkCgIdInfo i _ _ _) <- rngVarEnv static_binds ],
+               ptext SLIT("local binds for:"),
+               vcat [ ppr i | (MkCgIdInfo i _ _ _) <- rngVarEnv local_binds ],
+               ptext SLIT("SRT label") <+> pprCLabel srt
+             ])
+\end{code}
+
+%************************************************************************
+%*                                                                     *
 \subsection[Bindery-nuke-volatile]{Nuking volatile bindings}
 %*                                                                     *
 %************************************************************************
@@ -192,26 +248,19 @@ nukeVolatileBinds binds
 I {\em think} all looking-up is done through @getCAddrMode(s)@.
 
 \begin{code}
-getCAddrModeAndInfo :: Id -> FCode (CAddrMode, LambdaFormInfo)
+getCAddrModeAndInfo :: Id -> FCode (Id, CAddrMode, LambdaFormInfo)
 
 getCAddrModeAndInfo id
-  | not (isLocallyDefined name) || isWiredInName name
-    {- Why the "isWiredInName"?
-       Imagine you are compiling PrelBase.hs (a module that
-       supplies some of the wired-in values).  What can
-       happen is that the compiler will inject calls to
-       (e.g.) GHCbase.unpackPS, where-ever it likes -- it
-       assumes those values are ubiquitously available.
-       The main point is: it may inject calls to them earlier
-       in GHCbase.hs than the actual definition...
-    -}
-  = returnFC (global_amode, mkLFImported id)
+  | not (isLocalName name)
+  = returnFC (id, global_amode, mkLFImported id)
+       -- deals with imported or locally defined but externally visible ids
+       -- (CoreTidy makes all these into global names).
 
   | otherwise = -- *might* be a nested defn: in any case, it's something whose
                -- definition we will know about...
-    lookupBindC id `thenFC` \ (MkCgIdInfo _ volatile_loc stable_loc lf_info) ->
+    lookupBindC id `thenFC` \ (MkCgIdInfo id' volatile_loc stable_loc lf_info) ->
     idInfoPiecesToAmode kind volatile_loc stable_loc `thenFC` \ amode ->
-    returnFC (amode, lf_info)
+    returnFC (id', amode, lf_info)
   where
     name = getName id
     global_amode = CLbl (mkClosureLabel name) kind
@@ -219,7 +268,7 @@ getCAddrModeAndInfo id
 
 getCAddrMode :: Id -> FCode CAddrMode
 getCAddrMode name
-  = getCAddrModeAndInfo name `thenFC` \ (amode, _) ->
+  = getCAddrModeAndInfo name `thenFC` \ (_, amode, _) ->
     returnFC amode
 \end{code}
 
@@ -285,6 +334,9 @@ getVolatileRegs vars
 getArgAmodes :: [StgArg] -> FCode [CAddrMode]
 getArgAmodes [] = returnFC []
 getArgAmodes (atom:atoms)
+  | isStgTypeArg atom 
+  = getArgAmodes atoms
+  | otherwise
   = getArgAmode  atom  `thenFC` \ amode ->
     getArgAmodes atoms `thenFC` \ amodes ->
     returnFC ( amode : amodes )
@@ -292,43 +344,7 @@ getArgAmodes (atom:atoms)
 getArgAmode :: StgArg -> FCode CAddrMode
 
 getArgAmode (StgVarArg var) = getCAddrMode var         -- The common case
-
-getArgAmode (StgConArg (DataCon con))
-     {- Why does this case differ from StgVarArg?
-       Because the program might look like this:
-               data Foo a = Empty | Baz a
-               f a x = let c = Empty! a
-                       in h c
-       Now, when we go Core->Stg, we drop the type applications, 
-       so we can inline c, giving
-               f x = h Empty
-       Now we are referring to Empty as an argument (rather than in an STGCon), 
-       so we'll look it up with getCAddrMode.  We want to return an amode for
-       the static closure that we make for nullary constructors.  But if we blindly
-       go ahead with getCAddrMode we end up looking in the environment, and it ain't there!
-
-       This special case used to be in getCAddrModeAndInfo, but it doesn't work there.
-       Consider:
-               f a x = Baz a x
-       If the constructor Baz isn't inlined we simply want to treat it like any other
-       identifier, with a top level definition.  We don't want to spot that it's a constructor.
-
-       In short 
-               StgApp con args
-       and
-               StgCon con args
-       are treated differently; the former is a call to a bog standard function while the
-       latter uses the specially-labelled, pre-defined info tables etc for the constructor.
-
-       The way to think of this case in getArgAmode is that
-               SApp f Empty
-       is really
-               App f (StgCon Empty [])
-     -}
-  = returnFC (CLbl (mkStaticClosureLabel (dataConName con)) PtrRep)
-
-
-getArgAmode (StgConArg (Literal lit)) = returnFC (CLit lit)
+getArgAmode (StgLitArg lit) = returnFC (CLit lit)
 \end{code}
 
 %************************************************************************
@@ -369,11 +385,6 @@ bindNewToReg name magic_id lf_info
   where
     info = MkCgIdInfo name (RegLoc magic_id) NoStableLoc lf_info
 
-bindNewToLit name lit
-  = addBindC name info
-  where
-    info = MkCgIdInfo name NoVolatileLoc (LitLoc lit) (error "bindNewToLit")
-
 bindArgsToRegs :: [Id] -> [MagicId] -> Code
 bindArgsToRegs args regs
   = listCs (zipWithEqual "bindArgsToRegs" bind args regs)