[project @ 1999-05-18 15:03:33 by simonpj]
authorsimonpj <unknown>
Tue, 18 May 1999 15:03:51 +0000 (15:03 +0000)
committersimonpj <unknown>
Tue, 18 May 1999 15:03:51 +0000 (15:03 +0000)
RULES-NOTES

28 files changed:
ghc/compiler/DEPEND-NOTES
ghc/compiler/Makefile
ghc/compiler/basicTypes/BasicTypes.lhs
ghc/compiler/basicTypes/Const.lhs
ghc/compiler/basicTypes/DataCon.hi-boot
ghc/compiler/basicTypes/DataCon.lhs
ghc/compiler/basicTypes/Demand.lhs
ghc/compiler/basicTypes/Id.lhs
ghc/compiler/basicTypes/IdInfo.lhs
ghc/compiler/basicTypes/MkId.hi-boot
ghc/compiler/basicTypes/MkId.hi-boot-5
ghc/compiler/basicTypes/MkId.lhs
ghc/compiler/basicTypes/Module.lhs
ghc/compiler/basicTypes/Name.lhs
ghc/compiler/basicTypes/NameSet.lhs
ghc/compiler/basicTypes/RdrName.lhs
ghc/compiler/basicTypes/Unique.lhs
ghc/compiler/basicTypes/Var.lhs
ghc/compiler/basicTypes/VarEnv.lhs
ghc/compiler/basicTypes/VarSet.lhs
ghc/compiler/codeGen/CgCase.lhs
ghc/compiler/codeGen/CgClosure.lhs
ghc/compiler/codeGen/CgCon.lhs
ghc/compiler/codeGen/CgConTbls.lhs
ghc/compiler/codeGen/CgExpr.lhs
ghc/compiler/codeGen/CgMonad.lhs
ghc/compiler/codeGen/ClosureInfo.lhs
ghc/compiler/codeGen/CodeGen.lhs

index c1b64f3..2c0f82a 100644 (file)
@@ -1,3 +1,15 @@
+add types/InstEnv, InstEnv.hi-boot
+add coreSyn/CoreRules.*
+add coreSyn/CoreTidy.lhs
+add coreSyn/CoreFVs.lhs
+remove coreSyn/FreeVars.lhs
+add coreSyn/Subst.*
+remove simplCore/MagicUFs.*
+
+remove specialise/SpecEnv.*
+
+
+
 ToDo
 ~~~~
 * Test effect of eta-expanding past (case x of ..)
 ToDo
 ~~~~
 * Test effect of eta-expanding past (case x of ..)
@@ -62,45 +74,43 @@ ToDo
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The Name/Var/Type group is a bit complicated. Here's the deal
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The Name/Var/Type group is a bit complicated. Here's the deal
+Things in brackets are what the module *uses*.
+A 'loop' indicates a use from a module compiled later
 
 
-       Name, PrimRep, FieldLabel (uses Type.Type)
+       Name, PrimRep, FieldLabel (loop Type.Type)
 then
 then
-       Var (uses Const.Con, IdInfo.IdInfo, Type.GenType, Type.Kind)
+       Var (loop Const.Con, loop IdInfo.IdInfo, 
+            loop Type.GenType, loop Type.Kind)
 then
 then
-       VarEnv, VarSet
+       VarEnv, VarSet, ThinAir
 then
 then
-       Class (uses TyCon.TyCon, Type.Type, SpecEnv.SpecEnv)
+       Class (loop TyCon.TyCon, loop Type.Type, loop InstEnv.InstEnv)
 then
 then
-       TyCon (uses Type.Type, Type.Kind, DataCon.DataCon)
+       TyCon (loop Type.Type, loop Type.Kind, loop DataCon.DataCon)
 then
 then
-       Type (uses [DataCon.DataCon])
+       Type (loop DataCon.DataCon, loop Subst.substTy)
 then
 then
-       DataCon, TysPrim, Unify, SpecEnv, PprType
+       DataCon, TysPrim, Unify, PprType
 then
 then
-       IdInfo, TysWiredIn (uses DataCon.mkDataCon, [MkId.mkDataConId])
+       InstEnv (Unify)
 then
 then
-       PrimOp (uses PprType, TysWiredIn)
+       IdInfo (loop CoreRules.CoreRules) 
+       TysWiredIn (DataCon.mkDataCon, loop MkId.mkDataConId)
 then
 then
-       Const (needs PrimOp, [TysWiredIn.stringTy])
+       PrimOp (PprType, TysWiredIn, IdInfo.StrictnessInfo)
 then
 then
-       Id (needs Const.Con(..)), CoreSyn
+       Const (PrimOp.PrimOp, TysWiredIn.stringTy)
 then
 then
-       CoreUtils, OccurAnal
+       Id (Const.Con(..)), CoreSyn
 then
 then
-       CoreUnfold (uses OccurAnal)
+       CoreUtils (loop PprCore.pprCoreExpr), CoreFVs
+then   
+       OccurAnal (ThinAir.noRepStrs -- an awkward dependency)
 then
 then
-       MkId (uses CoreUnfold)
-       
-
-PrimOp uses TysWiredIn
-
+       CoreUnfold (loop OccurAnal.globalOccurAnalyse)
+then
+       Rules (Unfolding), Subst (Unfolding, CoreFVs), CoreTidy (noUnfolding)
+then
+       MkId (CoreUnfold.mkUnfolding, Subst)
 
 
-Add
-~~~
-basicTypes/DataCon.lhs
-basicTypes/DataCon.hi-boot
 
 
-Remove
-~~~~~~
-specialise/SpecUtils.lhs
-basicTypes/IdUtils.lhs
index 63c090f..21bd8a1 100644 (file)
@@ -1,5 +1,5 @@
 # -----------------------------------------------------------------------------
 # -----------------------------------------------------------------------------
-# $Id: Makefile,v 1.57 1999/05/14 11:23:47 simonm Exp $
+# $Id: Makefile,v 1.58 1999/05/18 15:03:34 simonpj Exp $
 
 TOP = ..
 include $(TOP)/mk/boilerplate.mk
 
 TOP = ..
 include $(TOP)/mk/boilerplate.mk
@@ -182,6 +182,7 @@ parser/U_literal_HC_OPTS    = -fvia-C '-\#include"hspincl.h"'
 parser/U_match_HC_OPTS                 = -fvia-C '-\#include"hspincl.h"'
 parser/U_maybe_HC_OPTS                 = -fvia-C '-\#include"hspincl.h"'
 parser/U_qid_HC_OPTS           = -fvia-C '-\#include"hspincl.h"'
 parser/U_match_HC_OPTS                 = -fvia-C '-\#include"hspincl.h"'
 parser/U_maybe_HC_OPTS                 = -fvia-C '-\#include"hspincl.h"'
 parser/U_qid_HC_OPTS           = -fvia-C '-\#include"hspincl.h"'
+parser/U_rulevar_HC_OPTS       = -fvia-C '-\#include"hspincl.h"'
 parser/U_tree_HC_OPTS          = -H12m -fvia-C '-\#include"hspincl.h"'
 parser/U_ttype_HC_OPTS                 = -fvia-C '-\#include"hspincl.h"'
 
 parser/U_tree_HC_OPTS          = -H12m -fvia-C '-\#include"hspincl.h"'
 parser/U_ttype_HC_OPTS                 = -fvia-C '-\#include"hspincl.h"'
 
index 5625103..39daeec 100644 (file)
@@ -16,14 +16,14 @@ types that
 module BasicTypes(
        Version, Arity, 
        Unused, unused,
 module BasicTypes(
        Version, Arity, 
        Unused, unused,
-       Fixity(..), FixityDirection(..), StrictnessMark(..),
-       NewOrData(..), TopLevelFlag(..), RecFlag(..)
+       Fixity(..), FixityDirection(..), defaultFixity,
+       NewOrData(..), 
+       RecFlag(..), isRec, isNonRec,
+       TopLevelFlag(..), isTopLevel, isNotTopLevel
    ) where
 
 #include "HsVersions.h"
 
    ) where
 
 #include "HsVersions.h"
 
-import {-# SOURCE #-} DataCon ( DataCon )
-import {-# SOURCE #-} Type    ( Type )
 import Outputable
 \end{code}
 
 import Outputable
 \end{code}
 
@@ -86,6 +86,9 @@ instance Outputable FixityDirection where
 
 instance Eq Fixity where               -- Used to determine if two fixities conflict
   (Fixity p1 dir1) == (Fixity p2 dir2) = p1==p2 && dir1 == dir2
 
 instance Eq Fixity where               -- Used to determine if two fixities conflict
   (Fixity p1 dir1) == (Fixity p2 dir2) = p1==p2 && dir1 == dir2
+
+
+defaultFixity = Fixity 9 InfixL
 \end{code}
 
 
 \end{code}
 
 
@@ -113,6 +116,14 @@ data NewOrData
 data TopLevelFlag
   = TopLevel
   | NotTopLevel
 data TopLevelFlag
   = TopLevel
   | NotTopLevel
+
+isTopLevel, isNotTopLevel :: TopLevelFlag -> Bool
+
+isNotTopLevel NotTopLevel = True
+isNotTopLevel TopLevel    = False
+
+isTopLevel TopLevel    = True
+isTopLevel NotTopLevel  = False
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -124,16 +135,12 @@ data TopLevelFlag
 \begin{code} 
 data RecFlag = Recursive 
             | NonRecursive
 \begin{code} 
 data RecFlag = Recursive 
             | NonRecursive
-\end{code}
 
 
-%************************************************************************
-%*                                                                     *
-\subsection{Strictness indication}
-%*                                                                     *
-%************************************************************************
+isRec :: RecFlag -> Bool
+isRec Recursive    = True
+isRec NonRecursive = False
 
 
-\begin{code}
-data StrictnessMark = MarkedStrict
-                   | MarkedUnboxed DataCon [Type]
-                   | NotMarkedStrict
+isNonRec :: RecFlag -> Bool
+isNonRec Recursive    = False
+isNonRec NonRecursive = True
 \end{code}
 \end{code}
index 1a48d0c..ae4219d 100644 (file)
@@ -8,7 +8,8 @@ module Const (
        Con(..),
        conType, conPrimRep,
        conOkForApp, conOkForAlt, isWHNFCon, isDataCon,
        Con(..),
        conType, conPrimRep,
        conOkForApp, conOkForAlt, isWHNFCon, isDataCon,
-       conIsTrivial, conIsCheap,
+       conIsTrivial, conIsCheap, conIsDupable, conStrictness, 
+       conOkForSpeculation,
 
        DataCon, PrimOp,        -- For completeness
 
 
        DataCon, PrimOp,        -- For completeness
 
@@ -26,12 +27,14 @@ module Const (
 import TysPrim         ( charPrimTy, addrPrimTy, floatPrimTy, doublePrimTy,
                          intPrimTy, wordPrimTy, int64PrimTy, word64PrimTy
                        )
 import TysPrim         ( charPrimTy, addrPrimTy, floatPrimTy, doublePrimTy,
                          intPrimTy, wordPrimTy, int64PrimTy, word64PrimTy
                        )
-import PrimOp          ( PrimOp, primOpType, primOpIsCheap )
+import PrimOp          ( PrimOp, primOpType, primOpIsDupable,
+                         primOpIsCheap, primOpStrictness, primOpOkForSpeculation )
 import PrimRep         ( PrimRep(..) )
 import PrimRep         ( PrimRep(..) )
-import DataCon         ( DataCon, dataConType, dataConTyCon, isNullaryDataCon )
+import DataCon         ( DataCon, dataConType, dataConTyCon, isNullaryDataCon, dataConRepStrictness )
 import TyCon           ( isNewTyCon )
 import Type            ( Type, typePrimRep )
 import PprType         ( pprParendType )
 import TyCon           ( isNewTyCon )
 import Type            ( Type, typePrimRep )
 import PprType         ( pprParendType )
+import Demand          ( Demand )
 import CStrings                ( stringToC, charToC, charToEasyHaskell )
 
 import Outputable
 import CStrings                ( stringToC, charToC, charToEasyHaskell )
 
 import Outputable
@@ -74,6 +77,11 @@ conType (DataCon dc)  = dataConType dc
 conType (Literal lit) = literalType lit
 conType (PrimOp op)   = primOpType op
 
 conType (Literal lit) = literalType lit
 conType (PrimOp op)   = primOpType op
 
+conStrictness :: Con -> ([Demand], Bool)
+conStrictness (DataCon dc)  = (dataConRepStrictness dc, False)
+conStrictness (PrimOp op)   = primOpStrictness op
+conStrictness (Literal lit) = ([], False)
+
 conPrimRep :: Con -> PrimRep   -- Only data valued constants
 conPrimRep (DataCon dc)  = ASSERT( isNullaryDataCon dc) PtrRep
 conPrimRep (Literal lit) = literalPrimRep lit
 conPrimRep :: Con -> PrimRep   -- Only data valued constants
 conPrimRep (DataCon dc)  = ASSERT( isNullaryDataCon dc) PtrRep
 conPrimRep (Literal lit) = literalPrimRep lit
@@ -113,6 +121,18 @@ conIsTrivial con      = True
 conIsCheap (Literal lit) = not (isNoRepLit lit)
 conIsCheap (DataCon con) = True
 conIsCheap (PrimOp op)   = primOpIsCheap op
 conIsCheap (Literal lit) = not (isNoRepLit lit)
 conIsCheap (DataCon con) = True
 conIsCheap (PrimOp op)   = primOpIsCheap op
+
+-- conIsDupable is true for constants whose applications we are willing
+-- to duplicate in different case branches; i.e no issue about loss of
+-- work, just space
+conIsDupable (Literal lit) = not (isNoRepLit lit)
+conIsDupable (DataCon con) = True
+conIsDupable (PrimOp op)   = primOpIsDupable op
+
+-- Similarly conOkForSpeculation
+conOkForSpeculation (Literal lit) = True
+conOkForSpeculation (DataCon con) = True
+conOkForSpeculation (PrimOp op)   = primOpOkForSpeculation op
 \end{code}
 
 
 \end{code}
 
 
index 3761c8f..511160d 100644 (file)
@@ -1,5 +1,6 @@
 _interface_ DataCon 1
 _exports_
 _interface_ DataCon 1
 _exports_
-DataCon DataCon ;
+DataCon DataCon dataConType ;
 _declarations_
 1 data DataCon ;
 _declarations_
 1 data DataCon ;
+1 dataConType _:_ DataCon -> Type.Type ;;
index 0ecb8e0..d916dcb 100644 (file)
@@ -11,18 +11,23 @@ module DataCon (
        dataConType, dataConSig, dataConName, dataConTag,
        dataConOrigArgTys, dataConArgTys, dataConRawArgTys, dataConTyCon,
        dataConFieldLabels, dataConStrictMarks, dataConSourceArity,
        dataConType, dataConSig, dataConName, dataConTag,
        dataConOrigArgTys, dataConArgTys, dataConRawArgTys, dataConTyCon,
        dataConFieldLabels, dataConStrictMarks, dataConSourceArity,
-       dataConNumFields, dataConNumInstArgs, dataConId,
+       dataConNumFields, dataConNumInstArgs, dataConId, dataConRepStrictness,
        isNullaryDataCon, isTupleCon, isUnboxedTupleCon,
        isNullaryDataCon, isTupleCon, isUnboxedTupleCon,
-       isExistentialDataCon
+       isExistentialDataCon,
+
+       StrictnessMark(..),     -- Representation visible to MkId only
+       markedStrict, notMarkedStrict, markedUnboxed, maybeMarkedUnboxed
     ) where
 
 #include "HsVersions.h"
 
     ) where
 
 #include "HsVersions.h"
 
+import {-# SOURCE #-} Subst( substTy, mkTyVarSubst )
+
 import CmdLineOpts     ( opt_DictsStrict )
 import TysPrim
 import Type            ( Type, ThetaType, TauType,
                          mkSigmaTy, mkFunTys, mkTyConApp, 
 import CmdLineOpts     ( opt_DictsStrict )
 import TysPrim
 import Type            ( Type, ThetaType, TauType,
                          mkSigmaTy, mkFunTys, mkTyConApp, 
-                         mkTyVarTys, mkDictTy, substTy,
+                         mkTyVarTys, mkDictTy,
                          splitAlgTyConApp_maybe
                        )
 import PprType
                          splitAlgTyConApp_maybe
                        )
 import PprType
@@ -31,9 +36,9 @@ import TyCon          ( TyCon, tyConDataCons, isDataTyCon,
 import Class           ( classTyCon )
 import Name            ( Name, NamedThing(..), nameUnique, isLocallyDefinedName )
 import Var             ( TyVar, Id )
 import Class           ( classTyCon )
 import Name            ( Name, NamedThing(..), nameUnique, isLocallyDefinedName )
 import Var             ( TyVar, Id )
-import VarEnv
 import FieldLabel      ( FieldLabel )
 import FieldLabel      ( FieldLabel )
-import BasicTypes      ( StrictnessMark(..), Arity )
+import BasicTypes      ( Arity )
+import Demand          ( Demand, wwStrict, wwLazy )
 import Outputable
 import Unique          ( Unique, Uniquable(..) )
 import CmdLineOpts     ( opt_UnboxStrictFields )
 import Outputable
 import Unique          ( Unique, Uniquable(..) )
 import CmdLineOpts     ( opt_UnboxStrictFields )
@@ -136,6 +141,32 @@ but the rep type is
 Actually, the unboxed part isn't implemented yet!
 
 
 Actually, the unboxed part isn't implemented yet!
 
 
+%************************************************************************
+%*                                                                     *
+\subsection{Strictness indication}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+data StrictnessMark = MarkedStrict
+                   | MarkedUnboxed DataCon [Type]
+                   | NotMarkedStrict
+
+markedStrict    = MarkedStrict
+notMarkedStrict = NotMarkedStrict
+markedUnboxed   = MarkedUnboxed (panic "markedUnboxed1") (panic "markedUnboxed2")
+
+maybeMarkedUnboxed (MarkedUnboxed dc tys) = Just (dc,tys)
+maybeMarkedUnboxed other                 = Nothing
+\end{code}
+
+
+%************************************************************************
+%*                                                                     *
+\subsection{Instances}
+%*                                                                     *
+%************************************************************************
+
 \begin{code}
 instance Eq DataCon where
     a == b = getUnique a == getUnique b
 \begin{code}
 instance Eq DataCon where
     a == b = getUnique a == getUnique b
@@ -161,6 +192,13 @@ instance Show DataCon where
     showsPrec p con = showsPrecSDoc p (ppr con)
 \end{code}
 
     showsPrec p con = showsPrecSDoc p (ppr con)
 \end{code}
 
+
+%************************************************************************
+%*                                                                     *
+\subsection{Consruction}
+%*                                                                     *
+%************************************************************************
+
 \begin{code}
 mkDataCon :: Name
          -> [StrictnessMark] -> [FieldLabel]
 \begin{code}
 mkDataCon :: Name
          -> [StrictnessMark] -> [FieldLabel]
@@ -307,6 +345,17 @@ dataConSourceArity :: DataCon -> Arity
        -- Source-level arity of the data constructor
 dataConSourceArity dc = length (dcOrigArgTys dc)
 
        -- Source-level arity of the data constructor
 dataConSourceArity dc = length (dcOrigArgTys dc)
 
+dataConRepStrictness :: DataCon -> [Demand]
+       -- Give the demands on the arguments of a 
+       -- Core constructor application (Con dc args)
+dataConRepStrictness dc
+  = go (dcRealStricts dc) 
+  where
+    go []                        = []
+    go (MarkedStrict        : ss) = wwStrict : go ss
+    go (NotMarkedStrict     : ss) = wwLazy   : go ss
+    go (MarkedUnboxed con _ : ss) = go (dcRealStricts con ++ ss)
+
 dataConSig :: DataCon -> ([TyVar], ThetaType, 
                          [TyVar], ThetaType, 
                          [TauType], TyCon)
 dataConSig :: DataCon -> ([TyVar], ThetaType, 
                          [TyVar], ThetaType, 
                          [TauType], TyCon)
@@ -325,12 +374,12 @@ dataConArgTys, dataConOrigArgTys :: DataCon
 
 dataConArgTys (MkData {dcRepArgTys = arg_tys, dcTyVars = tyvars, 
                       dcExTyVars = ex_tyvars, dcExTheta = ex_theta}) inst_tys
 
 dataConArgTys (MkData {dcRepArgTys = arg_tys, dcTyVars = tyvars, 
                       dcExTyVars = ex_tyvars, dcExTheta = ex_theta}) inst_tys
- = map (substTy (zipVarEnv (tyvars ++ ex_tyvars) inst_tys)) 
+ = map (substTy (mkTyVarSubst (tyvars ++ ex_tyvars) inst_tys)) 
        ([mkDictTy cls tys | (cls,tys) <- ex_theta] ++ arg_tys)
 
 dataConOrigArgTys (MkData {dcOrigArgTys = arg_tys, dcTyVars = tyvars, 
                       dcExTyVars = ex_tyvars, dcExTheta = ex_theta}) inst_tys
        ([mkDictTy cls tys | (cls,tys) <- ex_theta] ++ arg_tys)
 
 dataConOrigArgTys (MkData {dcOrigArgTys = arg_tys, dcTyVars = tyvars, 
                       dcExTyVars = ex_tyvars, dcExTheta = ex_theta}) inst_tys
- = map (substTy (zipVarEnv (tyvars ++ ex_tyvars) inst_tys)) 
+ = map (substTy (mkTyVarSubst (tyvars ++ ex_tyvars) inst_tys)) 
        ([mkDictTy cls tys | (cls,tys) <- ex_theta] ++ arg_tys)
 \end{code}
 
        ([mkDictTy cls tys | (cls,tys) <- ex_theta] ++ arg_tys)
 \end{code}
 
index f034216..7a4dbfe 100644 (file)
@@ -8,7 +8,7 @@ module Demand(
        Demand(..),
 
        wwLazy, wwStrict, wwUnpackData, wwUnpackNew, wwPrim, wwEnum, 
        Demand(..),
 
        wwLazy, wwStrict, wwUnpackData, wwUnpackNew, wwPrim, wwEnum, 
-       isStrict, isLazy, 
+       isStrict, isLazy, isPrim,
 
        pprDemands
      ) where
 
        pprDemands
      ) where
@@ -80,6 +80,10 @@ isStrict WwStrict = True
 isStrict WwEnum          = True
 isStrict WwPrim          = True
 isStrict _       = False
 isStrict WwEnum          = True
 isStrict WwPrim          = True
 isStrict _       = False
+
+isPrim :: Demand -> Bool
+isPrim WwPrim = True
+isPrim other  = False
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
index 6dec041..75e27aa 100644 (file)
@@ -8,16 +8,17 @@ module Id (
        Id, DictId,
 
        -- Simple construction
        Id, DictId,
 
        -- Simple construction
-       mkVanillaId, mkImportedId, mkSysLocal, mkUserLocal,
-       mkTemplateLocals, mkTemplateLocal, mkWildId, mkUserId,
+       mkId, mkVanillaId, mkSysLocal, mkUserLocal,
+       mkTemplateLocals, mkWildId, mkTemplateLocal,
 
        -- Taking an Id apart
 
        -- Taking an Id apart
-       idName, idType, idUnique, idInfo, idDetails,
+       idName, idType, idUnique, idInfo,
        idPrimRep, isId,
        recordSelectorFieldLabel,
 
        -- Modifying an Id
        idPrimRep, isId,
        recordSelectorFieldLabel,
 
        -- Modifying an Id
-       setIdName, setIdUnique, setIdType, setIdInfo,
+       setIdName, setIdUnique, setIdType, setIdNoDiscard, 
+       setIdInfo, modifyIdInfo, maybeModifyIdInfo,
 
        -- Predicates
        omitIfaceSigForId,
 
        -- Predicates
        omitIfaceSigForId,
@@ -26,14 +27,12 @@ module Id (
 
        -- Inline pragma stuff
        getInlinePragma, setInlinePragma, modifyInlinePragma, 
 
        -- Inline pragma stuff
        getInlinePragma, setInlinePragma, modifyInlinePragma, 
-       idWantsToBeINLINEd, idMustBeINLINEd, idMustNotBeINLINEd,
-       isSpecPragmaId,
-       
+       idMustBeINLINEd, idMustNotBeINLINEd,
 
 
-       isRecordSelector,
+       isSpecPragmaId, isRecordSelector,
        isPrimitiveId_maybe, isDataConId_maybe,
        isPrimitiveId_maybe, isDataConId_maybe,
-       isConstantId,
-       isBottomingId, idAppIsBottom,
+       isConstantId, isBottomingId, idAppIsBottom,
+       isExportedId, isUserExportedId,
 
        -- IdInfo stuff
        setIdUnfolding,
 
        -- IdInfo stuff
        setIdUnfolding,
@@ -61,20 +60,22 @@ module Id (
 #include "HsVersions.h"
 
 import {-# SOURCE #-} CoreUnfold ( Unfolding )
 #include "HsVersions.h"
 
 import {-# SOURCE #-} CoreUnfold ( Unfolding )
+import {-# SOURCE #-} CoreSyn    ( CoreRules )
 
 
-import Var             ( Id, DictId, VarDetails(..), 
-                         isId, mkId, 
-                         idName, idType, idUnique, idInfo, idDetails,
-                         setIdName, setVarType, setIdUnique, setIdInfo, modifyIdInfo,
+import Var             ( Id, DictId,
+                         isId, mkIdVar,
+                         idName, idType, idUnique, idInfo,
+                         setIdName, setVarType, setIdUnique, 
+                         setIdInfo, modifyIdInfo, maybeModifyIdInfo,
                          externallyVisibleId
                        )
 import VarSet
 import Type            ( Type, tyVarsOfType, typePrimRep, addFreeTyVars )
 import IdInfo
                          externallyVisibleId
                        )
 import VarSet
 import Type            ( Type, tyVarsOfType, typePrimRep, addFreeTyVars )
 import IdInfo
-import Demand          ( Demand )
+import Demand          ( Demand, isStrict, wwLazy )
 import Name            ( Name, OccName,
                          mkSysLocalName, mkLocalName,
 import Name            ( Name, OccName,
                          mkSysLocalName, mkLocalName,
-                         isWiredInName
+                         isWiredInName, isUserExportedName
                        ) 
 import Const           ( Con(..) )
 import PrimRep         ( PrimRep )
                        ) 
 import Const           ( Con(..) )
 import PrimRep         ( PrimRep )
@@ -106,15 +107,22 @@ infixl    1 `setIdUnfolding`,
 %*                                                                     *
 %************************************************************************
 
 %*                                                                     *
 %************************************************************************
 
-\begin{code}
-mkVanillaId :: Name -> Type -> Id
-mkVanillaId name ty = mkId name (addFreeTyVars ty) VanillaId noIdInfo
+Absolutely all Ids are made by mkId.  It 
+       a) Pins free-tyvar-info onto the Id's type, 
+          where it can easily be found.
+       b) Ensures that exported Ids are 
 
 
-mkImportedId :: Name -> Type -> IdInfo -> Id
-mkImportedId name ty info = mkId name (addFreeTyVars ty) VanillaId info
+\begin{code}
+mkId :: Name -> Type -> IdInfo -> Id
+mkId name ty info = mkIdVar name (addFreeTyVars ty) info'
+                 where
+                   info' | isUserExportedName name = setNoDiscardInfo info
+                         | otherwise               = info
+\end{code}
 
 
-mkUserId :: Name -> Type -> Id
-mkUserId name ty = mkVanillaId name ty
+\begin{code}
+mkVanillaId :: Name -> Type -> Id
+mkVanillaId name ty = mkId name ty vanillaIdInfo
 
 -- SysLocal: for an Id being created by the compiler out of thin air...
 -- UserLocal: an Id with a name the user might recognize...
 
 -- SysLocal: for an Id being created by the compiler out of thin air...
 -- UserLocal: an Id with a name the user might recognize...
@@ -163,27 +171,6 @@ idPrimRep :: Id -> PrimRep
 idPrimRep id = typePrimRep (idType id)
 \end{code}
 
 idPrimRep id = typePrimRep (idType id)
 \end{code}
 
-omitIfaceSigForId tells whether an Id's info is implied by other declarations,
-so we don't need to put its signature in an interface file, even if it's mentioned
-in some other interface unfolding.
-
-\begin{code}
-omitIfaceSigForId :: Id -> Bool
-omitIfaceSigForId id
-  | isWiredInName (idName id)
-  = True
-
-  | otherwise
-  = case idDetails id of
-       RecordSelId _  -> True  -- Includes dictionary selectors
-        ConstantId _   -> True
-               -- ConstantIds are implied by their type or class decl;
-               -- remember that all type and class decls appear in the interface file.
-               -- The dfun id must *not* be omitted, because it carries version info for
-               -- the instance decl
-
-       other          -> False -- Don't omit!
-\end{code}
 
 %************************************************************************
 %*                                                                     *
 
 %************************************************************************
 %*                                                                     *
@@ -192,28 +179,75 @@ omitIfaceSigForId id
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
+idFlavour :: Id -> IdFlavour
+idFlavour id = flavourInfo (idInfo id)
+
+setIdNoDiscard :: Id -> Id
+setIdNoDiscard id      -- Make an Id into a NoDiscardId, unless it is already
+  = modifyIdInfo setNoDiscardInfo id
+
 recordSelectorFieldLabel :: Id -> FieldLabel
 recordSelectorFieldLabel :: Id -> FieldLabel
-recordSelectorFieldLabel id = case idDetails id of
+recordSelectorFieldLabel id = case idFlavour id of
                                RecordSelId lbl -> lbl
 
                                RecordSelId lbl -> lbl
 
-isRecordSelector id = case idDetails id of
+isRecordSelector id = case idFlavour id of
                        RecordSelId lbl -> True
                        other           -> False
 
                        RecordSelId lbl -> True
                        other           -> False
 
-isPrimitiveId_maybe id = case idDetails id of
+isPrimitiveId_maybe id = case idFlavour id of
                            ConstantId (PrimOp op) -> Just op
                            other                  -> Nothing
 
                            ConstantId (PrimOp op) -> Just op
                            other                  -> Nothing
 
-isDataConId_maybe id = case idDetails id of
+isDataConId_maybe id = case idFlavour id of
                          ConstantId (DataCon con) -> Just con
                          other                    -> Nothing
 
                          ConstantId (DataCon con) -> Just con
                          other                    -> Nothing
 
-isConstantId id = case idDetails id of
+isConstantId id = case idFlavour id of
                    ConstantId _ -> True
                    other        -> False
                    ConstantId _ -> True
                    other        -> False
+
+isSpecPragmaId id = case idFlavour id of
+                       SpecPragmaId -> True
+                       other        -> False
+
+-- Don't drop a binding for an exported Id,
+-- if it otherwise looks dead.  
+isExportedId :: Id -> Bool
+isExportedId id = case idFlavour id of
+                       VanillaId -> False
+                       other     -> True       -- All the others are no-discard
+
+-- Say if an Id was exported by the user
+-- Implies isExportedId (see mkId above)
+isUserExportedId :: Id -> Bool
+isUserExportedId id = isUserExportedName (idName id)
 \end{code}
 
 
 \end{code}
 
 
+omitIfaceSigForId tells whether an Id's info is implied by other declarations,
+so we don't need to put its signature in an interface file, even if it's mentioned
+in some other interface unfolding.
+
+\begin{code}
+omitIfaceSigForId :: Id -> Bool
+omitIfaceSigForId id
+  | isWiredInName (idName id)
+  = True
+
+  | otherwise
+  = case idFlavour id of
+       RecordSelId _  -> True  -- Includes dictionary selectors
+        ConstantId _   -> True
+               -- ConstantIds are implied by their type or class decl;
+               -- remember that all type and class decls appear in the interface file.
+               -- The dfun id must *not* be omitted, because it carries version info for
+               -- the instance decl
+
+       other          -> False -- Don't omit!
+\end{code}
+
+
+
 %************************************************************************
 %*                                                                     *
 \subsection{IdInfo stuff}
 %************************************************************************
 %*                                                                     *
 \subsection{IdInfo stuff}
@@ -227,7 +261,7 @@ getIdArity :: Id -> ArityInfo
 getIdArity id = arityInfo (idInfo id)
 
 setIdArity :: Id -> ArityInfo -> Id
 getIdArity id = arityInfo (idInfo id)
 
 setIdArity :: Id -> ArityInfo -> Id
-setIdArity id arity = modifyIdInfo id (arity `setArityInfo`)
+setIdArity id arity = modifyIdInfo (`setArityInfo` arity) id
 
        ---------------------------------
        -- STRICTNESS
 
        ---------------------------------
        -- STRICTNESS
@@ -235,7 +269,7 @@ getIdStrictness :: Id -> StrictnessInfo
 getIdStrictness id = strictnessInfo (idInfo id)
 
 setIdStrictness :: Id -> StrictnessInfo -> Id
 getIdStrictness id = strictnessInfo (idInfo id)
 
 setIdStrictness :: Id -> StrictnessInfo -> Id
-setIdStrictness id strict_info = modifyIdInfo id (strict_info `setStrictnessInfo`)
+setIdStrictness id strict_info = modifyIdInfo (`setStrictnessInfo` strict_info) id
 
 -- isBottomingId returns true if an application to n args would diverge
 isBottomingId :: Id -> Bool
 
 -- isBottomingId returns true if an application to n args would diverge
 isBottomingId :: Id -> Bool
@@ -250,7 +284,7 @@ getIdWorkerInfo :: Id -> WorkerInfo
 getIdWorkerInfo id = workerInfo (idInfo id)
 
 setIdWorkerInfo :: Id -> WorkerInfo -> Id
 getIdWorkerInfo id = workerInfo (idInfo id)
 
 setIdWorkerInfo :: Id -> WorkerInfo -> Id
-setIdWorkerInfo id work_info = modifyIdInfo id (work_info `setWorkerInfo`)
+setIdWorkerInfo id work_info = modifyIdInfo (`setWorkerInfo` work_info) id
 
        ---------------------------------
        -- UNFOLDING
 
        ---------------------------------
        -- UNFOLDING
@@ -258,7 +292,7 @@ getIdUnfolding :: Id -> Unfolding
 getIdUnfolding id = unfoldingInfo (idInfo id)
 
 setIdUnfolding :: Id -> Unfolding -> Id
 getIdUnfolding id = unfoldingInfo (idInfo id)
 
 setIdUnfolding :: Id -> Unfolding -> Id
-setIdUnfolding id unfolding = modifyIdInfo id (unfolding `setUnfoldingInfo`)
+setIdUnfolding id unfolding = modifyIdInfo (`setUnfoldingInfo` unfolding) id
 
        ---------------------------------
        -- DEMAND
 
        ---------------------------------
        -- DEMAND
@@ -266,7 +300,7 @@ getIdDemandInfo :: Id -> Demand
 getIdDemandInfo id = demandInfo (idInfo id)
 
 setIdDemandInfo :: Id -> Demand -> Id
 getIdDemandInfo id = demandInfo (idInfo id)
 
 setIdDemandInfo :: Id -> Demand -> Id
-setIdDemandInfo id demand_info = modifyIdInfo id (demand_info `setDemandInfo`)
+setIdDemandInfo id demand_info = modifyIdInfo (`setDemandInfo` demand_info) id
 
        ---------------------------------
        -- UPDATE INFO
 
        ---------------------------------
        -- UPDATE INFO
@@ -274,15 +308,15 @@ getIdUpdateInfo :: Id -> UpdateInfo
 getIdUpdateInfo id = updateInfo (idInfo id)
 
 setIdUpdateInfo :: Id -> UpdateInfo -> Id
 getIdUpdateInfo id = updateInfo (idInfo id)
 
 setIdUpdateInfo :: Id -> UpdateInfo -> Id
-setIdUpdateInfo id upd_info = modifyIdInfo id (upd_info `setUpdateInfo`)
+setIdUpdateInfo id upd_info = modifyIdInfo (`setUpdateInfo` upd_info) id
 
        ---------------------------------
        -- SPECIALISATION
 
        ---------------------------------
        -- SPECIALISATION
-getIdSpecialisation :: Id -> IdSpecEnv
+getIdSpecialisation :: Id -> CoreRules
 getIdSpecialisation id = specInfo (idInfo id)
 
 getIdSpecialisation id = specInfo (idInfo id)
 
-setIdSpecialisation :: Id -> IdSpecEnv -> Id
-setIdSpecialisation id spec_info = modifyIdInfo id (spec_info `setSpecInfo`)
+setIdSpecialisation :: Id -> CoreRules -> Id
+setIdSpecialisation id spec_info = modifyIdInfo (`setSpecInfo` spec_info) id
 
        ---------------------------------
        -- CAF INFO
 
        ---------------------------------
        -- CAF INFO
@@ -290,7 +324,7 @@ getIdCafInfo :: Id -> CafInfo
 getIdCafInfo id = cafInfo (idInfo id)
 
 setIdCafInfo :: Id -> CafInfo -> Id
 getIdCafInfo id = cafInfo (idInfo id)
 
 setIdCafInfo :: Id -> CafInfo -> Id
-setIdCafInfo id caf_info = modifyIdInfo id (caf_info `setCafInfo`)
+setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id
 
        ---------------------------------
        -- CPR INFO
 
        ---------------------------------
        -- CPR INFO
@@ -298,8 +332,7 @@ getIdCprInfo :: Id -> CprInfo
 getIdCprInfo id = cprInfo (idInfo id)
 
 setIdCprInfo :: Id -> CprInfo -> Id
 getIdCprInfo id = cprInfo (idInfo id)
 
 setIdCprInfo :: Id -> CprInfo -> Id
-setIdCprInfo id cpr_info = modifyIdInfo id (cpr_info `setCprInfo`)
-
+setIdCprInfo id cpr_info = modifyIdInfo (`setCprInfo` cpr_info) id
 \end{code}
 
 
 \end{code}
 
 
@@ -313,28 +346,17 @@ getInlinePragma :: Id -> InlinePragInfo
 getInlinePragma id = inlinePragInfo (idInfo id)
 
 setInlinePragma :: Id -> InlinePragInfo -> Id
 getInlinePragma id = inlinePragInfo (idInfo id)
 
 setInlinePragma :: Id -> InlinePragInfo -> Id
-setInlinePragma id prag = modifyIdInfo id (setInlinePragInfo prag)
+setInlinePragma id prag = modifyIdInfo (`setInlinePragInfo` prag) id
 
 modifyInlinePragma :: Id -> (InlinePragInfo -> InlinePragInfo) -> Id
 
 modifyInlinePragma :: Id -> (InlinePragInfo -> InlinePragInfo) -> Id
-modifyInlinePragma id fn = modifyIdInfo id (\info -> setInlinePragInfo (fn (inlinePragInfo info)) info)
-
-idWantsToBeINLINEd :: Id -> Bool
-idWantsToBeINLINEd id = case getInlinePragma id of
-                         IWantToBeINLINEd -> True
-                         IMustBeINLINEd   -> True
-                         other            -> False
+modifyInlinePragma id fn = modifyIdInfo (\info -> info `setInlinePragInfo` (fn (inlinePragInfo info))) id
 
 idMustNotBeINLINEd id = case getInlinePragma id of
                          IMustNotBeINLINEd -> True
 
 idMustNotBeINLINEd id = case getInlinePragma id of
                          IMustNotBeINLINEd -> True
-                         IAmASpecPragmaId  -> True
                          IAmALoopBreaker   -> True
                          other             -> False
 
 idMustBeINLINEd id =  case getInlinePragma id of
                        IMustBeINLINEd -> True
                        other          -> False
                          IAmALoopBreaker   -> True
                          other             -> False
 
 idMustBeINLINEd id =  case getInlinePragma id of
                        IMustBeINLINEd -> True
                        other          -> False
-
-isSpecPragmaId id = case getInlinePragma id of
-                       IAmASpecPragmaId -> True
-                       other            -> False
 \end{code}
 \end{code}
index 892dd20..83f932d 100644 (file)
@@ -10,7 +10,12 @@ Haskell. [WDP 94/11])
 module IdInfo (
        IdInfo,         -- Abstract
 
 module IdInfo (
        IdInfo,         -- Abstract
 
-       noIdInfo,
+       vanillaIdInfo, mkIdInfo,
+
+       -- Flavour
+       IdFlavour(..), flavourInfo, 
+       setNoDiscardInfo, zapSpecPragInfo, copyIdInfo,
+       ppFlavourInfo,
 
        -- Arity
        ArityInfo(..),
 
        -- Arity
        ArityInfo(..),
@@ -39,7 +44,7 @@ module IdInfo (
        inlinePragInfo, setInlinePragInfo, notInsideLambda,
 
        -- Specialisation
        inlinePragInfo, setInlinePragInfo, notInsideLambda,
 
        -- Specialisation
-       IdSpecEnv, specInfo, setSpecInfo,
+       specInfo, setSpecInfo,
 
        -- Update
        UpdateInfo, UpdateSpec,
 
        -- Update
        UpdateInfo, UpdateSpec,
@@ -51,30 +56,48 @@ module IdInfo (
         -- Constructed Product Result Info
         CprInfo(..), cprInfo, setCprInfo, ppCprInfo, noCprInfo,
 
         -- Constructed Product Result Info
         CprInfo(..), cprInfo, setCprInfo, ppCprInfo, noCprInfo,
 
+       -- Zapping
+       zapLamIdInfo, zapFragileIdInfo,
+
         -- Lambda-bound variable info
         -- Lambda-bound variable info
-        LBVarInfo(..), lbvarInfo, setLBVarInfo, noLBVarInfo,
+        LBVarInfo(..), lbvarInfo, setLBVarInfo, noLBVarInfo
     ) where
 
 #include "HsVersions.h"
 
 
     ) where
 
 #include "HsVersions.h"
 
 
-import {-# SOURCE #-} CoreUnfold ( Unfolding, noUnfolding )
-import {-# SOURCE #-} CoreSyn   ( CoreExpr )
+import {-# SOURCE #-} CoreUnfold ( Unfolding, noUnfolding, hasUnfolding )
+import {-# SOURCE #-} CoreSyn   ( CoreExpr, CoreRules, emptyCoreRules, isEmptyCoreRules )
+import {-# SOURCE #-} Const     ( Con )
 
 import Var              ( Id )
 
 import Var              ( Id )
-import SpecEnv         ( SpecEnv, emptySpecEnv )
-import Demand          ( Demand,  isLazy, wwLazy, pprDemands )
+import FieldLabel      ( FieldLabel )
+import Demand          ( Demand, isStrict, isLazy, wwLazy, pprDemands )
 import Type             ( UsageAnn )
 import Outputable      
 import Type             ( UsageAnn )
 import Outputable      
-
 import Maybe            ( isJust )
 
 import Maybe            ( isJust )
 
+infixl         1 `setUpdateInfo`,
+         `setDemandInfo`,
+         `setStrictnessInfo`,
+         `setSpecInfo`,
+         `setArityInfo`,
+         `setInlinePragInfo`,
+         `setUnfoldingInfo`,
+         `setCprInfo`,
+         `setWorkerInfo`,
+         `setCafInfo`
+       -- infixl so you can say (id `set` a `set` b)
 \end{code}
 
 An @IdInfo@ gives {\em optional} information about an @Id@.  If
 present it never lies, but it may not be present, in which case there
 is always a conservative assumption which can be made.
 
 \end{code}
 
 An @IdInfo@ gives {\em optional} information about an @Id@.  If
 present it never lies, but it may not be present, in which case there
 is always a conservative assumption which can be made.
 
+       There is one exception: the 'flavour' is *not* optional.
+       You must not discard it.
+       It used to be in Var.lhs, but that seems unclean.
+
 Two @Id@s may have different info even though they have the same
 @Unique@ (and are hence the same @Id@); for example, one might lack
 the properties attached to the other.
 Two @Id@s may have different info even though they have the same
 @Unique@ (and are hence the same @Id@); for example, one might lack
 the properties attached to the other.
@@ -87,53 +110,138 @@ case.  KSW 1999-04).
 \begin{code}
 data IdInfo
   = IdInfo {
 \begin{code}
 data IdInfo
   = IdInfo {
-       arityInfo :: ArityInfo,                 -- Its arity
-       demandInfo :: Demand,                   -- Whether or not it is definitely demanded
-       specInfo :: IdSpecEnv,                  -- Specialisations of this function which exist
-       strictnessInfo :: StrictnessInfo,       -- Strictness properties
-        workerInfo :: WorkerInfo,               -- Pointer to Worker Function
-       unfoldingInfo :: Unfolding,             -- Its unfolding
-       updateInfo :: UpdateInfo,               -- Which args should be updated
-       cafInfo :: CafInfo,
-       cprInfo :: CprInfo,                     -- Function always constructs a product result
-        lbvarInfo :: LBVarInfo,                        -- Info about a lambda-bound variable
-       inlinePragInfo :: !InlinePragInfo       -- Inline pragmas
+       flavourInfo     :: IdFlavour,           -- NOT OPTIONAL
+       arityInfo       :: ArityInfo,           -- Its arity
+       demandInfo      :: Demand,              -- Whether or not it is definitely demanded
+       specInfo        :: CoreRules,           -- Specialisations of this function which exist
+       strictnessInfo  :: StrictnessInfo,      -- Strictness properties
+        workerInfo      :: WorkerInfo,          -- Pointer to Worker Function
+       unfoldingInfo   :: Unfolding,           -- Its unfolding
+       updateInfo      :: UpdateInfo,          -- Which args should be updated
+       cafInfo         :: CafInfo,
+       cprInfo         :: CprInfo,             -- Function always constructs a product result
+        lbvarInfo      :: LBVarInfo,           -- Info about a lambda-bound variable
+       inlinePragInfo  :: !InlinePragInfo      -- Inline pragmas
     }
 \end{code}
 
 Setters
 
 \begin{code}
     }
 \end{code}
 
 Setters
 
 \begin{code}
-setUpdateInfo    ud info = info { updateInfo = ud }
-setDemandInfo    dd info = info { demandInfo = dd }
-setStrictnessInfo st info = info { strictnessInfo = st }
-setWorkerInfo     wk info = info { workerInfo = wk }
-setSpecInfo      sp info = info { specInfo = sp }
-setArityInfo     ar info = info { arityInfo = ar  }
-setInlinePragInfo pr info = info { inlinePragInfo = pr }
-setUnfoldingInfo  uf info = info { unfoldingInfo = uf }
-setCafInfo        cf info = info { cafInfo = cf }
-setCprInfo        cp info = info { cprInfo = cp }
-setLBVarInfo      lb info = info { lbvarInfo = lb }
+setUpdateInfo    info ud = info { updateInfo = ud }
+setDemandInfo    info dd = info { demandInfo = dd }
+setStrictnessInfo info st = info { strictnessInfo = st }
+setWorkerInfo     info wk = info { workerInfo = wk }
+setSpecInfo      info sp = info { specInfo = sp }
+setArityInfo     info ar = info { arityInfo = ar  }
+setInlinePragInfo info pr = info { inlinePragInfo = pr }
+setUnfoldingInfo  info uf = info { unfoldingInfo = uf }
+setCafInfo        info cf = info { cafInfo = cf }
+setCprInfo        info cp = info { cprInfo = cp }
+setLBVarInfo      info lb = info { lbvarInfo = lb }
+
+setNoDiscardInfo  info = case flavourInfo info of
+                               VanillaId -> info { flavourInfo = NoDiscardId }
+                               other     -> info
+zapSpecPragInfo   info = case flavourInfo info of
+                               SpecPragmaId -> info { flavourInfo = VanillaId }
+                               other        -> info
+
+copyIdInfo :: IdInfo   -- From
+          -> IdInfo    -- To
+          -> IdInfo    -- To updated with stuff from From; except flavour unchanged
+-- copyIdInfo is used when shorting out a top-level binding
+--     f_local = BIG
+--     f = f_local
+-- where f is exported.  We are going to swizzle it around to
+--     f = BIG
+--     f_local = f
+-- but we must be careful to combine their IdInfos right.
+-- The fact that things can go wrong here is a bad sign, but I can't see
+-- how to make it 'patently right', so copyIdInfo is derived (pretty much) by trial and error
+--
+-- Here 'from' is f_local, 'to' is f.
+
+copyIdInfo from to = from { flavourInfo = flavourInfo to,
+                           specInfo = specInfo to
+                         }
+       -- It's important to propagate the inline pragmas from bndr
+       -- to exportd_id.  Ditto strictness etc.  This "bites" when we use an INLNE pragma:
+       --      {-# INLINE f #-}
+       --      f x = (x,x)
+       --
+       -- This becomes (where the "*" means INLINE prag)
+       --
+       --      M.f = /\a -> let mf* = \x -> (x,x) in mf
+       --
+       -- Now the mf floats out and we end up with the trivial binding
+       --
+       --      mf* = /\a -> \x -> (x,x)
+       --      M.f = mf
+       --
+       -- Now, when we short out the M.f = mf binding we must preserve the inline
+       -- pragma on the mf binding.
+       --
+       -- On the other hand, transformation rules may be attached to the 
+       -- 'to' Id, and we want to preserve them.  
 \end{code}
 
 
 \begin{code}
 \end{code}
 
 
 \begin{code}
-noIdInfo = IdInfo {
-               arityInfo       = UnknownArity,
-               demandInfo      = wwLazy,
-               specInfo        = emptySpecEnv,
-               strictnessInfo  = NoStrictnessInfo,
-               workerInfo      = noWorkerInfo,
-               unfoldingInfo   = noUnfolding,
-               updateInfo      = NoUpdateInfo,
-               cafInfo         = MayHaveCafRefs,
-               cprInfo         = NoCPRInfo,
-                lbvarInfo       = NoLBVarInfo,
-               inlinePragInfo  = NoInlinePragInfo
+vanillaIdInfo :: IdInfo
+vanillaIdInfo = mkIdInfo VanillaId
+
+mkIdInfo :: IdFlavour -> IdInfo
+mkIdInfo flv = IdInfo {
+                   flavourInfo         = flv,
+                   arityInfo           = UnknownArity,
+                   demandInfo          = wwLazy,
+                   specInfo            = emptyCoreRules,
+                   workerInfo          = Nothing,
+                   strictnessInfo      = NoStrictnessInfo,
+                   unfoldingInfo       = noUnfolding,
+                   updateInfo          = NoUpdateInfo,
+                   cafInfo             = MayHaveCafRefs,
+                   cprInfo             = NoCPRInfo,
+                   lbvarInfo           = NoLBVarInfo,
+                   inlinePragInfo      = NoInlinePragInfo
           }
 \end{code}
 
           }
 \end{code}
 
+
+%************************************************************************
+%*                                                                     *
+\subsection{Flavour}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+data IdFlavour
+  = VanillaId                          -- Most Ids are like this
+  | ConstantId Con                     -- The Id for a constant (data constructor or primop)
+  | RecordSelId FieldLabel             -- The Id for a record selector
+  | SpecPragmaId                       -- Don't discard these
+  | NoDiscardId                                -- Don't discard these either
+
+ppFlavourInfo :: IdFlavour -> SDoc
+ppFlavourInfo VanillaId       = empty
+ppFlavourInfo (ConstantId _)  = ptext SLIT("[Constr]")
+ppFlavourInfo (RecordSelId _) = ptext SLIT("[RecSel]")
+ppFlavourInfo SpecPragmaId    = ptext SLIT("[SpecPrag]")
+ppFlavourInfo NoDiscardId     = ptext SLIT("[NoDiscard]")
+\end{code}
+
+The @SpecPragmaId@ exists only to make Ids that are
+on the *LHS* of bindings created by SPECIALISE pragmas; 
+eg:            s = f Int d
+The SpecPragmaId is never itself mentioned; it
+exists solely so that the specialiser will find
+the call to f, and make specialised version of it.
+The SpecPragmaId binding is discarded by the specialiser
+when it gathers up overloaded calls.
+Meanwhile, it is not discarded as dead code.
+
+
 %************************************************************************
 %*                                                                     *
 \subsection[arity-IdInfo]{Arity info about an @Id@}
 %************************************************************************
 %*                                                                     *
 \subsection[arity-IdInfo]{Arity info about an @Id@}
@@ -175,9 +283,6 @@ ppArityInfo (ArityAtLeast arity) = hsep [ptext SLIT("__AL"), int arity]
 data InlinePragInfo
   = NoInlinePragInfo
 
 data InlinePragInfo
   = NoInlinePragInfo
 
-  | IAmASpecPragmaId   -- Used for spec-pragma Ids; don't discard or inline
-
-  | IWantToBeINLINEd   -- User INLINE pragma
   | IMustNotBeINLINEd  -- User NOINLINE pragma
 
   | IAmALoopBreaker    -- Used by the occurrence analyser to mark loop-breakers
   | IMustNotBeINLINEd  -- User NOINLINE pragma
 
   | IAmALoopBreaker    -- Used by the occurrence analyser to mark loop-breakers
@@ -202,35 +307,19 @@ data InlinePragInfo
 instance Outputable InlinePragInfo where
   ppr NoInlinePragInfo         = empty
   ppr IMustBeINLINEd           = ptext SLIT("__UU")
 instance Outputable InlinePragInfo where
   ppr NoInlinePragInfo         = empty
   ppr IMustBeINLINEd           = ptext SLIT("__UU")
-  ppr IWantToBeINLINEd         = ptext SLIT("__U")
   ppr IMustNotBeINLINEd        = ptext SLIT("__Unot")
   ppr IAmALoopBreaker          = ptext SLIT("__Ux")
   ppr IAmDead                  = ptext SLIT("__Ud")
   ppr (ICanSafelyBeINLINEd InsideLam _) = ptext SLIT("__Ul")
   ppr (ICanSafelyBeINLINEd _ _) = ptext SLIT("__Us")
   ppr IMustNotBeINLINEd        = ptext SLIT("__Unot")
   ppr IAmALoopBreaker          = ptext SLIT("__Ux")
   ppr IAmDead                  = ptext SLIT("__Ud")
   ppr (ICanSafelyBeINLINEd InsideLam _) = ptext SLIT("__Ul")
   ppr (ICanSafelyBeINLINEd _ _) = ptext SLIT("__Us")
-  ppr IAmASpecPragmaId                 = ptext SLIT("__US")
 
 instance Show InlinePragInfo where
   showsPrec p prag = showsPrecSDoc p (ppr prag)
 \end{code}
 
 
 instance Show InlinePragInfo where
   showsPrec p prag = showsPrecSDoc p (ppr prag)
 \end{code}
 
-The @IMustNotBeDiscarded@ exists only to make Ids that are
-on the *LHS* of bindings created by SPECIALISE pragmas; 
-eg:            s = f Int d
-The SpecPragmaId is never itself mentioned; it
-exists solely so that the specialiser will find
-the call to f, and make specialised version of it.
-The SpecPragmaId binding is discarded by the specialiser
-when it gathers up overloaded calls.
-Meanwhile, it is not discarded as dead code.
-
 \begin{code}
 data OccInfo
 \begin{code}
 data OccInfo
-  = StrictOcc          -- Occurs syntactically strictly;
-                       -- i.e. in a function position or case scrutinee
-
-  | LazyOcc            -- Not syntactically strict (*even* that of a strict function)
-                       -- or in a case branch where there's more than one alternative
+  = NotInsideLam
 
   | InsideLam          -- Inside a non-linear lambda (that is, a lambda which
                        -- is sure to be instantiated only once).
 
   | InsideLam          -- Inside a non-linear lambda (that is, a lambda which
                        -- is sure to be instantiated only once).
@@ -238,57 +327,17 @@ data OccInfo
                        -- dangerous because it might duplicate work.
 
 instance Outputable OccInfo where
                        -- dangerous because it might duplicate work.
 
 instance Outputable OccInfo where
-  ppr StrictOcc = text "s"
-  ppr LazyOcc   = empty
-  ppr InsideLam = text "l"
+  ppr NotInsideLam = empty
+  ppr InsideLam    = text "l"
 
 
 notInsideLambda :: OccInfo -> Bool
 
 
 notInsideLambda :: OccInfo -> Bool
-notInsideLambda StrictOcc = True
-notInsideLambda LazyOcc   = True
-notInsideLambda InsideLam = False
+notInsideLambda NotInsideLam = True
+notInsideLambda InsideLam    = False
 \end{code}
 
 %************************************************************************
 %*                                                                     *
 \end{code}
 
 %************************************************************************
 %*                                                                     *
-\subsection[specialisation-IdInfo]{Specialisation info about an @Id@}
-%*                                                                     *
-%************************************************************************
-
-A @IdSpecEnv@ holds details of an @Id@'s specialisations. 
-
-\begin{code}
-type IdSpecEnv = SpecEnv CoreExpr
-\end{code}
-
-For example, if \tr{f}'s @SpecEnv@ contains the mapping:
-\begin{verbatim}
-       [List a, b]  ===>  (\d -> f' a b)
-\end{verbatim}
-then when we find an application of f to matching types, we simply replace
-it by the matching RHS:
-\begin{verbatim}
-       f (List Int) Bool ===>  (\d -> f' Int Bool)
-\end{verbatim}
-All the stuff about how many dictionaries to discard, and what types
-to apply the specialised function to, are handled by the fact that the
-SpecEnv contains a template for the result of the specialisation.
-
-There is one more exciting case, which is dealt with in exactly the same
-way.  If the specialised value is unboxed then it is lifted at its
-definition site and unlifted at its uses.  For example:
-
-       pi :: forall a. Num a => a
-
-might have a specialisation
-
-       [Int#] ===>  (case pi' of Lift pi# -> pi#)
-
-where pi' :: Lift Int# is the specialised version of pi.
-
-
-%************************************************************************
-%*                                                                     *
 \subsection[strictness-IdInfo]{Strictness info about an @Id@}
 %*                                                                     *
 %************************************************************************
 \subsection[strictness-IdInfo]{Strictness info about an @Id@}
 %*                                                                     *
 %************************************************************************
@@ -432,6 +481,86 @@ ppCafInfo NoCafRefs = ptext SLIT("__C")
 ppCafInfo MayHaveCafRefs = empty
 \end{code}
 
 ppCafInfo MayHaveCafRefs = empty
 \end{code}
 
+
+%************************************************************************
+%*                                                                     *
+\subsection[CAF-IdInfo]{CAF-related information}
+%*                                                                     *
+%************************************************************************
+
+zapFragileIdInfo is used when cloning binders, mainly in the
+simplifier.  We must forget about used-once information because that
+isn't necessarily correct in the transformed program.
+Also forget specialisations and unfoldings because they would need
+substitution to be correct.  (They get pinned back on separately.)
+
+\begin{code}
+zapFragileIdInfo :: IdInfo -> Maybe IdInfo
+zapFragileIdInfo info@(IdInfo {inlinePragInfo  = inline_prag, 
+                              specInfo         = rules, 
+                              unfoldingInfo    = unfolding})
+  |  not is_fragile_inline_prag 
+        -- We must forget about whether it was marked safe-to-inline,
+       -- because that isn't necessarily true in the simplified expression.
+       -- This is important because expressions may  be re-simplified
+
+  && isEmptyCoreRules rules
+       -- Specialisations would need substituting.  They get pinned
+       -- back on separately.
+
+  && not (hasUnfolding unfolding)
+       -- This is very important; occasionally a let-bound binder is used
+       -- as a binder in some lambda, in which case its unfolding is utterly
+       -- bogus.  Also the unfolding uses old binders so if we left it we'd
+       -- have to substitute it. Much better simply to give the Id a new
+       -- unfolding each time, which is what the simplifier does.
+  = Nothing
+
+  | otherwise
+  = Just (info {inlinePragInfo = safe_inline_prag, 
+               specInfo        = emptyCoreRules,
+               unfoldingInfo   = noUnfolding})
+
+  where
+    is_fragile_inline_prag = case inline_prag of
+                               ICanSafelyBeINLINEd _ _ -> True
+
+-- We used to say the dead-ness was fragile, but I don't
+-- see why it is.  Furthermore, deadness is a pain to lose;
+-- see Simplify.mkDupableCont (Select ...)
+--                             IAmDead                 -> True
+
+                               other                   -> False
+
+       -- Be careful not to destroy real 'pragma' info
+    safe_inline_prag | is_fragile_inline_prag = NoInlinePragInfo
+                    | otherwise              = inline_prag
+\end{code}
+
+
+@zapLamIdInfo@ is used for lambda binders that turn out to to be
+part of an unsaturated lambda
+
+\begin{code}
+zapLamIdInfo :: IdInfo -> Maybe IdInfo
+zapLamIdInfo info@(IdInfo {inlinePragInfo = inline_prag, demandInfo = demand})
+  | is_safe_inline_prag && not (isStrict demand)
+  = Nothing
+  | otherwise
+  = Just (info {inlinePragInfo = safe_inline_prag,
+               demandInfo = wwLazy})
+  where
+    is_safe_inline_prag = case inline_prag of
+                               ICanSafelyBeINLINEd dup_danger nalts -> notInsideLambda dup_danger
+                               other                                -> True
+
+    safe_inline_prag    = case inline_prag of
+                               ICanSafelyBeINLINEd _ nalts
+                                     -> ICanSafelyBeINLINEd InsideLam nalts
+                               other -> inline_prag
+\end{code}
+
+
 %************************************************************************
 %*                                                                     *
 \subsection[cpr-IdInfo]{Constructed Product Result info about an @Id@}
 %************************************************************************
 %*                                                                     *
 \subsection[cpr-IdInfo]{Constructed Product Result info about an @Id@}
index 09a7f14..1069e9e 100644 (file)
@@ -1,5 +1,6 @@
 _interface_ MkId 1
 _exports_
 _interface_ MkId 1
 _exports_
-MkId mkDataConId ;
+MkId mkDataConId mkPrimitiveId ;
 _declarations_
 _declarations_
-1 mkDataConId _:_ DataCon.DataCon -> Var.Id ;;
+1 mkDataConId   _:_ DataCon.DataCon -> Var.Id ;;
+1 mkPrimitiveId _:_ PrimOp.PrimOp -> Var.Id ;;
index 6dd3a40..10a40e8 100644 (file)
@@ -1,3 +1,5 @@
 __interface MkId 1 0 where
 __interface MkId 1 0 where
-__export MkId mkDataConId ;
+__export MkId mkDataConId mkPrimitiveId ;
 1 mkDataConId :: DataCon.DataCon -> Var.Id ;
 1 mkDataConId :: DataCon.DataCon -> Var.Id ;
+1 mkPrimitiveId :: PrimOp.PrimOp -> Var.Id ;
+
index af3dc38..d13463e 100644 (file)
@@ -16,55 +16,71 @@ module MkId (
        mkSpecPragmaId, mkWorkerId,
 
        mkDictFunId, mkDefaultMethodId,
        mkSpecPragmaId, mkWorkerId,
 
        mkDictFunId, mkDefaultMethodId,
-       mkMethodSelId, mkSuperDictSelId, 
+       mkDictSelId,
 
        mkDataConId,
        mkRecordSelId,
        mkNewTySelId,
 
        mkDataConId,
        mkRecordSelId,
        mkNewTySelId,
-       mkPrimitiveId
+       mkPrimitiveId,
+
+       -- And some particular Ids; see below for why they are wired in
+       wiredInIds,
+       unsafeCoerceId, realWorldPrimId,
+       eRROR_ID, rEC_SEL_ERROR_ID, pAT_ERROR_ID, rEC_CON_ERROR_ID,
+       rEC_UPD_ERROR_ID, iRREFUT_PAT_ERROR_ID, nON_EXHAUSTIVE_GUARDS_ERROR_ID,
+       nO_METHOD_BINDING_ERROR_ID, aBSENT_ERROR_ID, pAR_ERROR_ID
     ) where
 
 #include "HsVersions.h"
 
     ) where
 
 #include "HsVersions.h"
 
-import {-# SOURCE #-} CoreUnfold ( mkUnfolding )
 
 
-import TysWiredIn      ( boolTy )
+import TysPrim         ( openAlphaTyVars, alphaTyVar, alphaTy, 
+                         intPrimTy, realWorldStatePrimTy
+                       )
+import TysWiredIn      ( boolTy, charTy, mkListTy )
+import PrelMods                ( pREL_ERR, pREL_GHC )
 import Type            ( Type, ThetaType,
                          mkDictTy, mkTyConApp, mkTyVarTys, mkFunTys, mkFunTy, mkSigmaTy,
 import Type            ( Type, ThetaType,
                          mkDictTy, mkTyConApp, mkTyVarTys, mkFunTys, mkFunTy, mkSigmaTy,
-                         mkForAllTys, isUnLiftedType, substTopTheta,
-                         splitSigmaTy, splitFunTy_maybe, splitAlgTyConApp, unUsgTy,
+                         isUnLiftedType, mkForAllTys, mkTyVarTy, 
+                         splitSigmaTy, splitFunTy_maybe, splitAlgTyConApp,
+                         splitFunTys, splitForAllTys, unUsgTy,
+                         mkUsgTy, UsageAnn(..)
                        )
                        )
+import Module          ( Module )
+import CoreUnfold      ( mkUnfolding )
+import Subst           ( mkTopTyVarSubst, substTheta )
 import TyCon           ( TyCon, isNewTyCon, tyConDataCons, isDataTyCon )
 import Class           ( Class, classBigSig, classTyCon )
 import TyCon           ( TyCon, isNewTyCon, tyConDataCons, isDataTyCon )
 import Class           ( Class, classBigSig, classTyCon )
-import Var             ( Id, TyVar, VarDetails(..), mkId )
+import Var             ( Id, TyVar )
 import VarEnv          ( zipVarEnv )
 import Const           ( Con(..) )
 import VarEnv          ( zipVarEnv )
 import Const           ( Con(..) )
-import Name            ( mkDerivedName, mkWiredInIdName, 
+import Name            ( mkDerivedName, mkWiredInIdName, mkLocalName, 
                          mkWorkerOcc, mkSuperDictSelOcc,
                          Name, NamedThing(..),
                        )
                          mkWorkerOcc, mkSuperDictSelOcc,
                          Name, NamedThing(..),
                        )
-import PrimOp          ( PrimOp, primOpSig, primOpOcc, primOpUniq )
-import DataCon         ( DataCon, dataConStrictMarks, dataConFieldLabels, 
+import OccName         ( mkSrcVarOcc )
+import PrimOp          ( PrimOp(DataToTagOp), primOpSig, mkPrimOpIdName )
+import Demand          ( wwStrict )
+import DataCon         ( DataCon, StrictnessMark(..), dataConStrictMarks, dataConFieldLabels, 
                          dataConArgTys, dataConSig, dataConRawArgTys
                        )
                          dataConArgTys, dataConSig, dataConRawArgTys
                        )
-import Id              ( idType,
-                         mkUserLocal, mkVanillaId, mkTemplateLocals,
+import Id              ( idType, mkId,
+                         mkVanillaId, mkTemplateLocals,
                          mkTemplateLocal, setInlinePragma
                        )
                          mkTemplateLocal, setInlinePragma
                        )
-import IdInfo          ( noIdInfo,
-                         exactArity, setUnfoldingInfo, 
+import IdInfo          ( vanillaIdInfo, mkIdInfo,
+                         exactArity, setUnfoldingInfo, setCafInfo,
                          setArityInfo, setInlinePragInfo,
                          setArityInfo, setInlinePragInfo,
-                         InlinePragInfo(..), IdInfo
+                         mkStrictnessInfo, setStrictnessInfo,
+                         IdFlavour(..), InlinePragInfo(..), CafInfo(..), IdInfo
                        )
 import FieldLabel      ( FieldLabel, FieldLabelTag, mkFieldLabel, fieldLabelName, 
                          firstFieldLabelTag, allFieldLabelTags
                        )
 import CoreSyn
                        )
 import FieldLabel      ( FieldLabel, FieldLabelTag, mkFieldLabel, fieldLabelName, 
                          firstFieldLabelTag, allFieldLabelTags
                        )
 import CoreSyn
-import PrelVals                ( rEC_SEL_ERROR_ID )
-import PrelMods                ( pREL_GHC )
 import Maybes
 import Maybes
-import BasicTypes      ( Arity, StrictnessMark(..) )
-import Unique          ( Unique )
+import BasicTypes      ( Arity )
+import Unique
 import Maybe            ( isJust )
 import Outputable
 import Util            ( assoc )
 import Maybe            ( isJust )
 import Outputable
 import Util            ( assoc )
@@ -74,13 +90,46 @@ import List         ( nub )
 
 %************************************************************************
 %*                                                                     *
 
 %************************************************************************
 %*                                                                     *
+\subsection{Wired in Ids}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+wiredInIds
+  = [  -- These error-y things are wired in because we don't yet have
+       -- a way to express in an interface file that the result type variable
+       -- is 'open'; that is can be unified with an unboxed type
+       -- 
+       -- [The interface file format now carry such information, but there's
+       --  no way yet of expressing at the definition site for these error-reporting
+       --  functions that they have an 'open' result type. -- sof 1/99]
+
+      aBSENT_ERROR_ID
+    , eRROR_ID
+    , iRREFUT_PAT_ERROR_ID
+    , nON_EXHAUSTIVE_GUARDS_ERROR_ID
+    , nO_METHOD_BINDING_ERROR_ID
+    , pAR_ERROR_ID
+    , pAT_ERROR_ID
+    , rEC_CON_ERROR_ID
+    , rEC_UPD_ERROR_ID
+
+       -- These two can't be defined in Haskell
+    , realWorldPrimId
+    , unsafeCoerceId
+    , getTagId
+    ]
+\end{code}
+
+%************************************************************************
+%*                                                                     *
 \subsection{Easy ones}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
 mkSpecPragmaId occ uniq ty loc
 \subsection{Easy ones}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
 mkSpecPragmaId occ uniq ty loc
-  = mkUserLocal occ uniq ty loc `setInlinePragma` IAmASpecPragmaId
+  = mkId (mkLocalName uniq occ loc) ty (mkIdInfo SpecPragmaId)
        -- Maybe a SysLocal?  But then we'd lose the location
 
 mkDefaultMethodId dm_name rec_c ty
        -- Maybe a SysLocal?  But then we'd lose the location
 
 mkDefaultMethodId dm_name rec_c ty
@@ -101,7 +150,6 @@ mkDataConId :: DataCon -> Id
 mkDataConId data_con
   = mkId (getName data_con)
         id_ty
 mkDataConId data_con
   = mkId (getName data_con)
         id_ty
-        (ConstantId (DataCon data_con))
         (dataConInfo data_con)
   where
     (tyvars, theta, ex_tyvars, ex_theta, arg_tys, tycon) = dataConSig data_con
         (dataConInfo data_con)
   where
     (tyvars, theta, ex_tyvars, ex_theta, arg_tys, tycon) = dataConSig data_con
@@ -129,21 +177,29 @@ Notice that
 * We have to check that we can construct Data dictionaries for
   the types a and Int.  Once we've done that we can throw d1 away too.
 
 * We have to check that we can construct Data dictionaries for
   the types a and Int.  Once we've done that we can throw d1 away too.
 
-* We use (case p of ...) to evaluate p, rather than "seq" because
+* We use (case p of q -> ...) to evaluate p, rather than "seq" because
   all that matters is that the arguments are evaluated.  "seq" is 
   very careful to preserve evaluation order, which we don't need
   to be here.
 
   all that matters is that the arguments are evaluated.  "seq" is 
   very careful to preserve evaluation order, which we don't need
   to be here.
 
+  You might think that we could simply give constructors some strictness
+  info, like PrimOps, and let CoreToStg do the let-to-case transformation.
+  But we don't do that because in the case of primops and functions strictness
+  is a *property* not a *requirement*.  In the case of constructors we need to
+  do something active to evaluate the argument.
+
+  Making an explicit case expression allows the simplifier to eliminate
+  it in the (common) case where the constructor arg is already evaluated.
+
 \begin{code}
 dataConInfo :: DataCon -> IdInfo
 
 dataConInfo data_con
 \begin{code}
 dataConInfo :: DataCon -> IdInfo
 
 dataConInfo data_con
-  = setInlinePragInfo IMustBeINLINEd $ -- Always inline constructors
-    setArityInfo (exactArity (n_dicts + n_ex_dicts + n_id_args)) $
-    setUnfoldingInfo unfolding $
-    noIdInfo
+  = mkIdInfo (ConstantId (DataCon data_con))
+    `setArityInfo` exactArity (n_dicts + n_ex_dicts + n_id_args)
+    `setUnfoldingInfo` unfolding
   where
   where
-        unfolding = mkUnfolding con_rhs
+        unfolding = mkUnfolding (Note InlineMe con_rhs)
 
        (tyvars, theta, ex_tyvars, ex_theta, orig_arg_tys, tycon) 
           = dataConSig data_con
 
        (tyvars, theta, ex_tyvars, ex_theta, orig_arg_tys, tycon) 
           = dataConSig data_con
@@ -226,12 +282,12 @@ mkRecordSelId field_label selector_ty
   = ASSERT( null theta && isDataTyCon tycon )
     sel_id
   where
   = ASSERT( null theta && isDataTyCon tycon )
     sel_id
   where
-    sel_id = mkId (fieldLabelName field_label) selector_ty
-                 (RecordSelId field_label) info
+    sel_id = mkId (fieldLabelName field_label) selector_ty info
 
 
-    info = exactArity 1        `setArityInfo` (
-          unfolding    `setUnfoldingInfo`
-          noIdInfo)
+    info = mkIdInfo (RecordSelId field_label)
+          `setArityInfo`       exactArity 1
+          `setUnfoldingInfo`   unfolding       
+          
        -- ToDo: consider adding further IdInfo
 
     unfolding = mkUnfolding sel_rhs
        -- ToDo: consider adding further IdInfo
 
     unfolding = mkUnfolding sel_rhs
@@ -278,12 +334,13 @@ Possibly overkill to do it this way:
 \begin{code}
 mkNewTySelId field_label selector_ty = sel_id
   where
 \begin{code}
 mkNewTySelId field_label selector_ty = sel_id
   where
-    sel_id = mkId (fieldLabelName field_label) selector_ty
-                 (RecordSelId field_label) info
+    sel_id = mkId (fieldLabelName field_label) selector_ty info
+                 
 
 
-    info = exactArity 1        `setArityInfo` (
-          unfolding    `setUnfoldingInfo`
-          noIdInfo)
+    info = mkIdInfo (RecordSelId field_label)
+          `setArityInfo`       exactArity 1    
+          `setUnfoldingInfo`   unfolding
+          
        -- ToDo: consider adding further IdInfo
 
     unfolding = mkUnfolding sel_rhs
        -- ToDo: consider adding further IdInfo
 
     unfolding = mkUnfolding sel_rhs
@@ -297,7 +354,6 @@ mkNewTySelId field_label selector_ty = sel_id
     [data_id] = mkTemplateLocals [data_ty]
     sel_rhs   = mkLams tyvars $ Lam data_id $
                Note (Coerce rhs_ty data_ty) (Var data_id)
     [data_id] = mkTemplateLocals [data_ty]
     sel_rhs   = mkLams tyvars $ Lam data_id $
                Note (Coerce rhs_ty data_ty) (Var data_id)
-
 \end{code}
 
 
 \end{code}
 
 
@@ -307,25 +363,6 @@ mkNewTySelId field_label selector_ty = sel_id
 %*                                                                     *
 %************************************************************************
 
 %*                                                                     *
 %************************************************************************
 
-\begin{code}
-mkSuperDictSelId :: Unique -> Class -> FieldLabelTag -> Type -> Id
-       -- The FieldLabelTag says which superclass is selected
-       -- So, for 
-       --      class (C a, C b) => Foo a b where ...
-       -- we get superclass selectors
-       --      Foo_sc1, Foo_sc2
-
-mkSuperDictSelId uniq clas index ty
-  = mkDictSelId name clas ty
-  where
-    name   = mkDerivedName (mkSuperDictSelOcc index) (getName clas) uniq
-
-       -- For method selectors the clean thing to do is
-       -- to give the method selector the same name as the class op itself.
-mkMethodSelId name clas ty
-  = mkDictSelId name clas ty
-\end{code}
-
 Selecting a field for a dictionary.  If there is just one field, then
 there's nothing to do.
 
 Selecting a field for a dictionary.  If there is just one field, then
 there's nothing to do.
 
@@ -333,15 +370,15 @@ there's nothing to do.
 mkDictSelId name clas ty
   = sel_id
   where
 mkDictSelId name clas ty
   = sel_id
   where
-    sel_id    = mkId name ty (RecordSelId field_lbl) info
+    sel_id    = mkId name ty info
     field_lbl = mkFieldLabel name ty tag
     tag       = assoc "MkId.mkDictSelId" ((sc_sel_ids ++ op_sel_ids) `zip` allFieldLabelTags) sel_id
 
     field_lbl = mkFieldLabel name ty tag
     tag       = assoc "MkId.mkDictSelId" ((sc_sel_ids ++ op_sel_ids) `zip` allFieldLabelTags) sel_id
 
-    info      = setInlinePragInfo IMustBeINLINEd $
-               setUnfoldingInfo  unfolding noIdInfo
-       -- The always-inline thing means we don't need any other IdInfo
-       -- We need "Must" inline because we don't create any bindigs for
-       -- the selectors.
+    info      = mkIdInfo (RecordSelId field_lbl)
+               `setUnfoldingInfo`  unfolding
+               
+       -- We no longer use 'must-inline' on record selectors.  They'll
+       -- inline like crazy if they scrutinise a constructor
 
     unfolding = mkUnfolding rhs
 
 
     unfolding = mkUnfolding rhs
 
@@ -370,25 +407,23 @@ mkDictSelId name clas ty
 %*                                                                     *
 %************************************************************************
 
 %*                                                                     *
 %************************************************************************
 
-
 \begin{code}
 mkPrimitiveId :: PrimOp -> Id
 mkPrimitiveId prim_op 
   = id
   where
 \begin{code}
 mkPrimitiveId :: PrimOp -> Id
 mkPrimitiveId prim_op 
   = id
   where
-    occ_name = primOpOcc  prim_op
-    key             = primOpUniq prim_op
     (tyvars,arg_tys,res_ty) = primOpSig prim_op
     (tyvars,arg_tys,res_ty) = primOpSig prim_op
-    ty       = mkForAllTys tyvars (mkFunTys arg_tys res_ty)
-    name    = mkWiredInIdName key pREL_GHC occ_name id
-    id      = mkId name ty (ConstantId (PrimOp prim_op)) info
+    ty   = mkForAllTys tyvars (mkFunTys arg_tys res_ty)
+    name = mkPrimOpIdName prim_op id
+    id   = mkId name ty info
                
                
-    info = setUnfoldingInfo unfolding $
-          setInlinePragInfo IMustBeINLINEd $
+    info = mkIdInfo (ConstantId (PrimOp prim_op))
+          `setUnfoldingInfo`   unfolding
+          `setInlinePragInfo`  IMustBeINLINEd
                -- The pragma @IMustBeINLINEd@ says that this Id absolutely 
                -- must be inlined.  It's only used for primitives, 
                -- because we don't want to make a closure for each of them.
                -- The pragma @IMustBeINLINEd@ says that this Id absolutely 
                -- must be inlined.  It's only used for primitives, 
                -- because we don't want to make a closure for each of them.
-          noIdInfo
+          
 
     unfolding = mkUnfolding rhs
 
 
     unfolding = mkUnfolding rhs
 
@@ -397,14 +432,6 @@ mkPrimitiveId prim_op
           mkPrimApp prim_op (map Type (mkTyVarTys tyvars) ++ map Var args)
 \end{code}
 
           mkPrimApp prim_op (map Type (mkTyVarTys tyvars) ++ map Var args)
 \end{code}
 
-\end{code}
-
-\begin{code}
-dyadic_fun_ty  ty = mkFunTys [ty, ty] ty
-monadic_fun_ty ty = ty `mkFunTy` ty
-compare_fun_ty ty = mkFunTys [ty, ty] boolTy
-\end{code}
-
 
 %************************************************************************
 %*                                                                     *
 
 %************************************************************************
 %*                                                                     *
@@ -424,7 +451,7 @@ mkDictFunId dfun_name clas inst_tyvars inst_tys inst_decl_theta
   = mkVanillaId dfun_name dfun_ty
   where
     (class_tyvars, sc_theta, _, _, _) = classBigSig clas
   = mkVanillaId dfun_name dfun_ty
   where
     (class_tyvars, sc_theta, _, _, _) = classBigSig clas
-    sc_theta' = substTopTheta (zipVarEnv class_tyvars inst_tys) sc_theta
+    sc_theta' = substTheta (mkTopTyVarSubst class_tyvars inst_tys) sc_theta
 
     dfun_theta = case inst_decl_theta of
                   []    -> []  -- If inst_decl_theta is empty, then we don't
 
     dfun_theta = case inst_decl_theta of
                   []    -> []  -- If inst_decl_theta is empty, then we don't
@@ -443,3 +470,164 @@ mkDictFunId dfun_name clas inst_tyvars inst_tys inst_decl_theta
 
     dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
 \end{code}
 
     dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
 \end{code}
+
+
+%************************************************************************
+%*                                                                     *
+\subsection{Un-definable}
+%*                                                                     *
+%************************************************************************
+
+These two can't be defined in Haskell.
+
+unsafeCoerce# isn't so much a PrimOp as a phantom identifier, that
+just gets expanded into a type coercion wherever it occurs.  Hence we
+add it as a built-in Id with an unfolding here.
+
+The type variables we use here are "open" type variables: this means
+they can unify with both unlifted and lifted types.  Hence we provide
+another gun with which to shoot yourself in the foot.
+
+\begin{code}
+unsafeCoerceId
+  = pcMiscPrelId unsafeCoerceIdKey pREL_GHC SLIT("unsafeCoerce#") ty info
+  where
+    info = vanillaIdInfo
+          `setUnfoldingInfo`   mkUnfolding rhs
+          `setInlinePragInfo`  IMustBeINLINEd 
+          
+
+    ty  = mkForAllTys [openAlphaTyVar,openBetaTyVar]
+                     (mkFunTy openAlphaTy openBetaTy)
+    [x] = mkTemplateLocals [openAlphaTy]
+    rhs = mkLams [openAlphaTyVar,openBetaTyVar,x] $
+         Note (Coerce openBetaTy openAlphaTy) (Var x)
+\end{code}
+
+
+@getTag#@ is another function which can't be defined in Haskell.  It needs to
+evaluate its argument and call the dataToTag# primitive.
+
+\begin{code}
+getTagId
+  = pcMiscPrelId getTagIdKey pREL_GHC SLIT("getTag#") ty info
+  where
+    info = vanillaIdInfo
+          `setUnfoldingInfo`   mkUnfolding rhs
+          `setInlinePragInfo`  IMustBeINLINEd 
+       -- We don't provide a defn for this; you must inline it
+
+    ty = mkForAllTys [alphaTyVar] (mkFunTy alphaTy intPrimTy)
+    [x,y] = mkTemplateLocals [alphaTy,alphaTy]
+    rhs = mkLams [alphaTyVar,x] $
+         Case (Var x) y [ (DEFAULT, [], 
+                  Con (PrimOp DataToTagOp) [Type alphaTy, Var y]) ]
+\end{code}
+
+@realWorld#@ used to be a magic literal, \tr{void#}.  If things get
+nasty as-is, change it back to a literal (@Literal@).
+
+\begin{code}
+realWorldPrimId        -- :: State# RealWorld
+  = pcMiscPrelId realWorldPrimIdKey pREL_GHC SLIT("realWorld#")
+                realWorldStatePrimTy
+                noCafIdInfo
+\end{code}
+
+
+%************************************************************************
+%*                                                                     *
+\subsection[PrelVals-error-related]{@error@ and friends; @trace@}
+%*                                                                     *
+%************************************************************************
+
+GHC randomly injects these into the code.
+
+@patError@ is just a version of @error@ for pattern-matching
+failures.  It knows various ``codes'' which expand to longer
+strings---this saves space!
+
+@absentErr@ is a thing we put in for ``absent'' arguments.  They jolly
+well shouldn't be yanked on, but if one is, then you will get a
+friendly message from @absentErr@ (rather than a totally random
+crash).
+
+@parError@ is a special version of @error@ which the compiler does
+not know to be a bottoming Id.  It is used in the @_par_@ and @_seq_@
+templates, but we don't ever expect to generate code for it.
+
+\begin{code}
+eRROR_ID
+  = pc_bottoming_Id errorIdKey pREL_ERR SLIT("error") errorTy
+rEC_SEL_ERROR_ID
+  = generic_ERROR_ID recSelErrIdKey SLIT("patError")
+pAT_ERROR_ID
+  = generic_ERROR_ID patErrorIdKey SLIT("patError")
+rEC_CON_ERROR_ID
+  = generic_ERROR_ID recConErrorIdKey SLIT("recConError")
+rEC_UPD_ERROR_ID
+  = generic_ERROR_ID recUpdErrorIdKey SLIT("recUpdError")
+iRREFUT_PAT_ERROR_ID
+  = generic_ERROR_ID irrefutPatErrorIdKey SLIT("irrefutPatError")
+nON_EXHAUSTIVE_GUARDS_ERROR_ID
+  = generic_ERROR_ID nonExhaustiveGuardsErrorIdKey SLIT("nonExhaustiveGuardsError")
+nO_METHOD_BINDING_ERROR_ID
+  = generic_ERROR_ID noMethodBindingErrorIdKey SLIT("noMethodBindingError")
+
+aBSENT_ERROR_ID
+  = pc_bottoming_Id absentErrorIdKey pREL_ERR SLIT("absentErr")
+       (mkSigmaTy [openAlphaTyVar] [] openAlphaTy)
+
+pAR_ERROR_ID
+  = pcMiscPrelId parErrorIdKey pREL_ERR SLIT("parError")
+    (mkSigmaTy [openAlphaTyVar] [] openAlphaTy) noCafIdInfo
+
+\end{code}
+
+
+%************************************************************************
+%*                                                                     *
+\subsection{Utilities}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+pcMiscPrelId :: Unique{-IdKey-} -> Module -> FAST_STRING -> Type -> IdInfo -> Id
+pcMiscPrelId key mod str ty info
+  = let
+       name = mkWiredInIdName key mod (mkSrcVarOcc str) imp
+       imp  = mkId name ty info -- the usual case...
+    in
+    imp
+    -- We lie and say the thing is imported; otherwise, we get into
+    -- a mess with dependency analysis; e.g., core2stg may heave in
+    -- random calls to GHCbase.unpackPS__.  If GHCbase is the module
+    -- being compiled, then it's just a matter of luck if the definition
+    -- will be in "the right place" to be in scope.
+
+pc_bottoming_Id key mod name ty
+ = pcMiscPrelId key mod name ty bottoming_info
+ where
+    bottoming_info = noCafIdInfo 
+                    `setStrictnessInfo` mkStrictnessInfo ([wwStrict], True)
+                    
+       -- these "bottom" out, no matter what their arguments
+
+generic_ERROR_ID u n = pc_bottoming_Id u pREL_ERR n errorTy
+
+-- Very useful...
+noCafIdInfo = vanillaIdInfo `setCafInfo` NoCafRefs
+
+(openAlphaTyVar:openBetaTyVar:_) = openAlphaTyVars
+openAlphaTy  = mkTyVarTy openAlphaTyVar
+openBetaTy   = mkTyVarTy openBetaTyVar
+
+errorTy  :: Type
+errorTy  = mkUsgTy UsMany $
+           mkSigmaTy [openAlphaTyVar] [] (mkFunTys [mkUsgTy UsOnce (mkListTy charTy)] 
+                                                   (mkUsgTy UsMany openAlphaTy))
+    -- Notice the openAlphaTyVar.  It says that "error" can be applied
+    -- to unboxed as well as boxed types.  This is OK because it never
+    -- returns, so the return type is irrelevant.
+\end{code}
+
index 2e6f46c..4320bc3 100644 (file)
@@ -9,43 +9,54 @@ Representing modules and their flavours.
 module Module 
     (
       Module               -- abstract, instance of Eq, Ord, Outputable
 module Module 
     (
       Module               -- abstract, instance of Eq, Ord, Outputable
+    , ModuleName
+
+    , moduleNameString         -- :: ModuleName -> EncodedString
+    , moduleNameUserString     -- :: ModuleName -> UserString
+
     , moduleString          -- :: Module -> EncodedString
     , moduleUserString      -- :: Module -> UserString
     , moduleString          -- :: Module -> EncodedString
     , moduleUserString      -- :: Module -> UserString
-    , moduleIfaceFlavour    -- :: Module -> IfaceFlavour
-    , moduleFS             -- :: Module -> EncodedFS
+    , moduleName           -- :: Module -> ModuleName
 
 
-    , mkBootModule          -- :: Module -> Module
-    , setModuleFlavour     -- :: IfaceFlavour -> Module -> Module
+    , mkVanillaModule      -- :: ModuleName -> Module
+    , mkThisModule         -- :: ModuleName -> Module
+    , mkPrelModule          -- :: UserString -> Module
 
 
-    , mkDynamicModule       -- :: Module -> Module
     , isDynamicModule       -- :: Module -> Bool
     , isDynamicModule       -- :: Module -> Bool
+    , isLibModule
 
     , mkSrcModule
 
     , mkSrcModule
-    , mkPrelModule          -- :: UserString -> Module
 
 
-    , mkSrcModuleFS         -- :: UserFS -> Module
-    , mkSysModuleFS         -- :: EncodedFS -> IfaceFlavour -> Module
-    , mkImportModuleFS      -- :: UserFS -> IfaceFlavour -> Module
+    , mkSrcModuleFS         -- :: UserFS    -> ModuleName
+    , mkSysModuleFS         -- :: EncodedFS -> ModuleName
 
 
-    , pprModule
-    , pprModuleSep
-    , pprModuleBoot
+    , pprModule, pprModuleName
  
  
-      -- IfaceFlavour
-    , IfaceFlavour
-    , hiFile
-    , hiBootFile           -- :: IfaceFlavour
-    , mkDynFlavour         -- :: Bool -> IfaceFlavour -> IfaceFlavour
+       -- DllFlavour
+    , DllFlavour, dll, notDll
+
+       -- ModFlavour
+    , ModFlavour, libMod, userMod
 
 
-    , bootFlavour           -- :: IfaceFlavour -> Bool
+       -- Where to find a .hi file
+    , WhereFrom(..), SearchPath, mkSearchPath
+    , ModuleHiMap, mkModuleHiMaps
 
     ) where
 
 #include "HsVersions.h"
 import OccName
 import Outputable
 
     ) where
 
 #include "HsVersions.h"
 import OccName
 import Outputable
-import CmdLineOpts ( opt_Static, opt_CompilingPrelude )
-
+import FiniteMap
+import CmdLineOpts     ( opt_Static, opt_CompilingPrelude, opt_WarnHiShadows )
+import Constants       ( interfaceFileFormatVersion )
+import Maybes          ( seqMaybe )
+import Maybe           ( fromMaybe )
+import Directory       ( doesFileExist )
+import DirUtils                ( getDirectoryContents )
+import List            ( intersperse )
+import Monad           ( foldM )
+import IO              ( hPutStrLn, stderr, isDoesNotExistError )
 \end{code}
 
 
 \end{code}
 
 
@@ -55,23 +66,6 @@ import CmdLineOpts ( opt_Static, opt_CompilingPrelude )
 %*                                                                     *
 %************************************************************************
 
 %*                                                                     *
 %************************************************************************
 
-The IfaceFlavour type is used mainly in an imported Name's Provenance
-to say whether the name comes from a regular .hi file, or whether it comes
-from a hand-written .hi-boot file.  This is important, because it has to be 
-propagated.  Suppose
-
-       C.hs imports B
-       B.hs imports A
-       A.hs imports C {-# SOURCE -#} ( f )
-
-Then in A.hi we may mention C.f, in an inlining.  When compiling B we *must not* 
-read C.f's details from C.hi, even if the latter happens to exist from an earlier
-compilation run.  So we use the name "C!f" in A.hi, and when looking for an interface
-file with details of C!f we look in C.hi-boot.  The "!" stuff is recorded in the
-IfaceFlavour in the Module of C.f in A. 
-
-Not particularly beautiful, but it works.
-
 A further twist to the tale is the support for dynamically linked libraries under
 Win32. Here, dealing with the use of global variables that's residing in a DLL
 requires special handling at the point of use (there's an extra level of indirection,
 A further twist to the tale is the support for dynamically linked libraries under
 Win32. Here, dealing with the use of global variables that's residing in a DLL
 requires special handling at the point of use (there's an extra level of indirection,
@@ -84,124 +78,308 @@ The logic for how an interface file is marked as corresponding to a module that'
 hiding in a DLL is explained elsewhere (ToDo: give renamer href here.)
 
 \begin{code}
 hiding in a DLL is explained elsewhere (ToDo: give renamer href here.)
 
 \begin{code}
-data IfaceFlavour = HiFile             -- The thing comes from a standard interface file
-                                       -- or from the source file itself
-                 | HiBootFile          -- ... or from a handwritten "hi-boot" interface file
-
-                 | HiDllFile           -- The thing comes from a standard interface file, but
-                                       -- it's corresponding object code is residing in a DLL.
-                                       -- (see above.)
-                 deriving( Eq )
-
-hiFile     = HiFile
-hiDllFile  = HiDllFile
-hiBootFile = HiBootFile
-
--- badly named, isn't clear whether the boolean deals with
--- the 'bootedness' or the 'DLLedness'. ToDo: improve.
-mkDynFlavour :: Bool{-is really dyn?-} -> IfaceFlavour -> IfaceFlavour
-mkDynFlavour True HiFile = HiDllFile
-mkDynFlavour _   x      = x
-
-instance Text IfaceFlavour where       -- Just used in debug prints of lex tokens
-  showsPrec n HiBootFile s = "!" ++ s
-  showsPrec n HiFile     s = s
-  showsPrec n HiDllFile  s = s
-
-bootFlavour :: IfaceFlavour -> Bool
-bootFlavour HiBootFile = True
-bootFlavour HiFile     = False
-bootFlavour HiDllFile  = False
+data DllFlavour = NotDll       -- Ordinary module
+               | Dll           -- The module's object code lives in a DLL.
+               deriving( Eq )
+
+dll    = Dll
+notDll = NotDll
+
+instance Text DllFlavour where -- Just used in debug prints of lex tokens
+  showsPrec n NotDll s = s
+  showsPrec n Dll    s = "dll " ++ s
 \end{code}
 
 
 %************************************************************************
 %*                                                                     *
 \end{code}
 
 
 %************************************************************************
 %*                                                                     *
-\subsection[Module]{The name of a module}
+\subsection{System/user module}
 %*                                                                     *
 %************************************************************************
 
 %*                                                                     *
 %************************************************************************
 
+We also track whether an imported module is from a 'system-ish' place.  In this case
+we don't record the fact that this module depends on it, nor usages of things
+inside it.  
+
 \begin{code}
 \begin{code}
-data Module = Module
-               EncodedFS
-               IfaceFlavour
+data ModFlavour = LibMod       -- A library-ish module
+               | UserMod       -- Not library-ish
+
+libMod  = LibMod
+userMod = UserMod
+\end{code}
+
+
+%************************************************************************
+%*                                                                     *
+\subsection{Where from}
+%*                                                                     *
+%************************************************************************
+
+The @WhereFrom@ type controls where the renamer looks for an interface file
+
+\begin{code}
+data WhereFrom = ImportByUser          -- Ordinary user import: look for M.hi
+              | ImportByUserSource     -- User {- SOURCE -}: look for M.hi-boot
+              | ImportBySystem         -- Non user import.  Look for M.hi if M is in
+                                       -- the module this module depends on, or is a system-ish module; 
+                                       -- M.hi-boot otherwise
+
+instance Outputable WhereFrom where
+  ppr ImportByUser       = empty
+  ppr ImportByUserSource = ptext SLIT("{- SOURCE -}")
+  ppr ImportBySystem     = ptext SLIT("{- SYSTEM IMPORT -}")
+\end{code}
+
+
+%************************************************************************
+%*                                                                     *
+\subsection{The name of a module}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+type ModuleName = EncodedFS
        -- Haskell module names can include the quote character ',
        -- so the module names have the z-encoding applied to them
        -- Haskell module names can include the quote character ',
        -- so the module names have the z-encoding applied to them
+
+type ModuleNameSet = FiniteMap ModuleName
+elemModuleNameSet  s x = elemFM s x
+moduleNameSetElems s   = eltsFM s
+
+
+pprModuleName :: ModuleName -> SDoc
+pprModuleName nm = pprEncodedFS nm
+
+moduleNameString :: ModuleName -> EncodedString
+moduleNameString mod = _UNPK_ mod
+
+moduleNameUserString :: ModuleName -> UserString
+moduleNameUserString mod = decode (_UNPK_ mod)
+
+mkSrcModule :: UserString -> ModuleName
+mkSrcModule s = _PK_ (encode s)
+
+mkSrcModuleFS :: UserFS -> ModuleName
+mkSrcModuleFS s = encodeFS s
+
+mkSysModuleFS :: EncodedFS -> ModuleName
+mkSysModuleFS s = s 
+\end{code}
+
+\begin{code}
+data Module = Module
+               ModuleName
+               ModFlavour
+               DllFlavour
 \end{code}
 
 \begin{code}
 instance Outputable Module where
   ppr = pprModule
 
 \end{code}
 
 \begin{code}
 instance Outputable Module where
   ppr = pprModule
 
--- Ignore the IfaceFlavour when comparing modules
 instance Eq Module where
 instance Eq Module where
-  (Module m1 _) == (Module m2 _) = m1 == m2
+  (Module m1 _  _) == (Module m2 _ _) = m1 == m2
 
 instance Ord Module where
 
 instance Ord Module where
-  (Module m1 _) `compare` (Module m2 _) = m1 `compare` m2
+  (Module m1 _ _) `compare` (Module m2 _ _) = m1 `compare` m2
 \end{code}
 
 
 \begin{code}
 pprModule :: Module -> SDoc
 \end{code}
 
 
 \begin{code}
 pprModule :: Module -> SDoc
-pprModule (Module mod _) = pprEncodedFS mod
-
-pprModuleSep, pprModuleBoot :: Module -> SDoc
-pprModuleSep (Module mod HiFile)     = dot
-pprModuleSep (Module mod HiDllFile)  = dot
-pprModuleSep (Module mod HiBootFile) = char '!'
-
-pprModuleBoot (Module mod HiFile)     = empty
-pprModuleBoot (Module mod HiDllFile)  = empty
-pprModuleBoot (Module mod HiBootFile) = char '!'
+pprModule (Module mod _ _) = pprEncodedFS mod
 \end{code}
 
 
 \begin{code}
 \end{code}
 
 
 \begin{code}
-mkSrcModule :: UserString -> Module
-mkSrcModule s = Module (_PK_ (encode s)) HiFile
+mkModule = Module
+
+mkVanillaModule :: ModuleName -> Module
+mkVanillaModule name = Module name UserMod NotDll
+
+mkThisModule :: ModuleName -> Module   -- The module being comiled
+mkThisModule name = Module name UserMod NotDll -- ToDo: correct Dll flag?
 
 
-mkPrelModule :: UserString -> Module
-mkPrelModule s = Module (_PK_ (encode s)) ilk
+mkPrelModule :: ModuleName -> Module
+mkPrelModule name = Module name sys dll
  where 
  where 
-  ilk
-   | opt_Static || opt_CompilingPrelude = HiFile
-   | otherwise = HiDllFile
+  sys | opt_CompilingPrelude = UserMod
+      | otherwise           = LibMod
 
 
-mkSrcModuleFS :: UserFS -> Module
-mkSrcModuleFS s = Module (encodeFS s) HiFile
+  dll | opt_Static || opt_CompilingPrelude = NotDll
+      | otherwise                         = Dll
 
 
-mkImportModuleFS :: UserFS -> IfaceFlavour -> Module
-mkImportModuleFS s hif = Module (encodeFS s) hif
+moduleString :: Module -> EncodedString
+moduleString (Module mod _ _) = _UNPK_ mod
+
+moduleName :: Module -> ModuleName
+moduleName (Module mod _ _) = mod
 
 
-mkSysModuleFS :: EncodedFS -> IfaceFlavour -> Module
-mkSysModuleFS s hif = Module s hif
+moduleUserString :: Module -> UserString
+moduleUserString (Module mod _ _) = moduleNameUserString mod
+\end{code}
 
 
-mkBootModule :: Module -> Module
-mkBootModule (Module s _) = Module s HiBootFile
+\begin{code}
+isDynamicModule :: Module -> Bool
+isDynamicModule (Module _ _ Dll)  = True
+isDynamicModule _                = False
 
 
-mkDynamicModule :: Module -> Module
-mkDynamicModule (Module s HiFile) = Module s HiDllFile
-mkDynamicModule m = m
+isLibModule :: Module -> Bool
+isLibModule (Module _ LibMod _) = True
+isLibModule _                  = False
+\end{code}
 
 
-setModuleFlavour :: IfaceFlavour -> Module -> Module
-setModuleFlavour hif (Module n _) = Module n hif
 
 
-moduleString :: Module -> EncodedString
-moduleString (Module mod _) = _UNPK_ mod
+%************************************************************************
+%*                                                                     *
+\subsection{Finding modules in the file system
+%*                                                                     *
+%************************************************************************
 
 
-moduleFS :: Module -> EncodedFS
-moduleFS (Module mod _) = mod
+\begin{code}
+type ModuleHiMap = FiniteMap ModuleName (String, Module)
+  -- Mapping from module name to 
+  --   * the file path of its corresponding interface file, 
+  --   * the Module, decorated with it's properties
+\end{code}
 
 
-moduleUserString :: Module -> UserString
-moduleUserString (Module mod _) = decode (_UNPK_ mod)
+(We allege that) it is quicker to build up a mapping from module names
+to the paths to their corresponding interface files once, than to search
+along the import part every time we slurp in a new module (which we 
+do quite a lot of.)
 
 
-moduleIfaceFlavour :: Module -> IfaceFlavour
-moduleIfaceFlavour (Module _ hif) = hif
+\begin{code}
+type SearchPath = [(String,String)]    -- List of (directory,suffix) pairs to search 
+                                        -- for interface files.
+
+mkModuleHiMaps :: SearchPath -> IO (ModuleHiMap, ModuleHiMap)
+mkModuleHiMaps dirs = foldM (getAllFilesMatching dirs) (env,env) dirs
+ where
+  env = emptyFM
+
+{- A pseudo file, currently "dLL_ifs.hi",
+   signals that the interface files
+   contained in a particular directory have got their
+   corresponding object codes stashed away in a DLL
+   
+   This stuff is only needed to deal with Win32 DLLs,
+   and conceivably we conditionally compile in support
+   for handling it. (ToDo?)
+-}
+dir_contain_dll_his = "dLL_ifs.hi"
+
+getAllFilesMatching :: SearchPath
+                   -> (ModuleHiMap, ModuleHiMap)
+                   -> (FilePath, String) 
+                   -> IO (ModuleHiMap, ModuleHiMap)
+getAllFilesMatching dirs hims (dir_path, suffix) = ( do
+    -- fpaths entries do not have dir_path prepended
+  fpaths  <- getDirectoryContents dir_path
+  is_dll <- catch
+               (if opt_Static || dir_path == "." then
+                    return NotDll
+                else
+                    do  exists <- doesFileExist (dir_path ++ '/': dir_contain_dll_his)
+                        return (if exists then Dll else NotDll)
+               )
+               (\ _ {-don't care-} -> return NotDll)
+  return (foldl (addModules is_dll) hims fpaths)
+  )  -- soft failure
+      `catch` 
+        (\ err -> do
+             hPutStrLn stderr
+                    ("Import path element `" ++ dir_path ++ 
+                     if (isDoesNotExistError err) then
+                        "' does not exist, ignoring."
+                     else
+                       "' couldn't read, ignoring.")
+              
+              return hims
+       )
+ where
+  
+       -- Dreadfully crude.  We want a better way to distinguish
+       -- "library-ish" modules.
+   is_sys | head dir_path == '/' = LibMod
+         | otherwise            = UserMod
+
+   xiffus       = reverse dotted_suffix 
+   dotted_suffix = case suffix of
+                     []       -> []
+                     ('.':xs) -> suffix
+                     ls       -> '.':ls
+
+   hi_boot_version_xiffus = 
+      reverse (show interfaceFileFormatVersion) ++ '-':hi_boot_xiffus
+   hi_boot_xiffus = "toob-ih." -- .hi-boot reversed!
+
+   addModules is_dll his@(hi_env, hib_env) filename = fromMaybe his $ 
+        FMAP add_hi   (go xiffus                rev_fname)     `seqMaybe`
+        FMAP add_vhib (go hi_boot_version_xiffus rev_fname)    `seqMaybe`
+       FMAP add_hib  (go hi_boot_xiffus         rev_fname)
+    where
+     rev_fname = reverse filename
+     path      = dir_path ++ '/':filename
+
+     mk_module mod_nm = Module mod_nm is_sys is_dll
+     add_hi    mod_nm = (addToFM_C addNewOne hi_env mod_nm (path, mk_module mod_nm), hib_env)
+     add_vhib  mod_nm = (hi_env, addToFM_C overrideNew hib_env mod_nm (path, mk_module mod_nm))
+     add_hib   mod_nm = (hi_env, addToFM_C addNewOne   hib_env mod_nm (path, mk_module mod_nm))
+
+
+   -- go prefix (prefix ++ stuff) == Just (reverse stuff)
+   go [] xs                    = Just (_PK_ (reverse xs))
+   go _  []                    = Nothing
+   go (x:xs) (y:ys) | x == y    = go xs ys 
+                   | otherwise = Nothing
+
+   addNewOne | opt_WarnHiShadows = conflict
+            | otherwise         = stickWithOld
+
+   stickWithOld old new = old
+   overrideNew  old new = new
+
+   conflict (old_path,mod) (new_path,_)
+    | old_path /= new_path = 
+        pprTrace "Warning: " (text "Identically named interface files present on the import path, " $$
+                             text (show old_path) <+> text "shadows" $$
+                             text (show new_path) $$
+                             text "on the import path: " <+> 
+                             text (concat (intersperse ":" (map fst dirs))))
+        (old_path,mod)
+    | otherwise = (old_path,mod)  -- don't warn about innocous shadowings.
 \end{code}
 
 \end{code}
 
+
+%*********************************************************
+%*                                                      *
+\subsection{Making a search path}
+%*                                                      *
+%*********************************************************
+
+@mkSearchPath@ takes a string consisting of a colon-separated list
+of directories and corresponding suffixes, and turns it into a list
+of (directory, suffix) pairs.  For example:
+
+\begin{verbatim}
+ mkSearchPath "foo%.hi:.%.p_hi:baz%.mc_hi"
+   = [("foo",".hi"),( ".", ".p_hi"), ("baz",".mc_hi")]
+\begin{verbatim}
+
 \begin{code}
 \begin{code}
-isDynamicModule :: Module -> Bool
-isDynamicModule (Module _ HiDllFile)  = True
-isDynamicModule _                    = False
+mkSearchPath :: Maybe String -> SearchPath
+mkSearchPath Nothing = [(".",".hi")]  -- ToDo: default should be to look in
+                                     -- the directory the module we're compiling
+                                     -- lives.
+mkSearchPath (Just s) = go s
+  where
+    go "" = []
+    go s  = 
+      case span (/= '%') s of
+       (dir,'%':rs) ->
+         case span (/= ':') rs of
+          (hisuf,_:rest) -> (dir,hisuf):go rest
+          (hisuf,[])     -> [(dir,hisuf)]
 \end{code}
 \end{code}
+
index 9c1fee1..0bd95d2 100644 (file)
@@ -12,7 +12,7 @@ module Name (
        Name,                                   -- Abstract
        mkLocalName, mkImportedLocalName, mkSysLocalName, 
        mkTopName,
        Name,                                   -- Abstract
        mkLocalName, mkImportedLocalName, mkSysLocalName, 
        mkTopName,
-       mkDerivedName, mkGlobalName,
+       mkDerivedName, mkGlobalName, mkKnownKeyGlobal,
        mkWiredInIdName,   mkWiredInTyConName,
        maybeWiredInIdName, maybeWiredInTyConName,
        isWiredInName,
        mkWiredInIdName,   mkWiredInTyConName,
        maybeWiredInIdName, maybeWiredInTyConName,
        isWiredInName,
@@ -21,7 +21,7 @@ module Name (
        tidyTopName, 
        nameOccName, nameModule, setNameOcc, nameRdrName, setNameModule,
 
        tidyTopName, 
        nameOccName, nameModule, setNameOcc, nameRdrName, setNameModule,
 
-       isExportedName, nameSrcLoc,
+       isUserExportedName, nameSrcLoc,
        isLocallyDefinedName,
 
        isSystemName, isLocalName, isGlobalName, isExternallyVisibleName,
        isLocallyDefinedName,
 
        isSystemName, isLocalName, isGlobalName, isExternallyVisibleName,
@@ -34,7 +34,6 @@ module Name (
 
        -- Class NamedThing and overloaded friends
        NamedThing(..),
 
        -- Class NamedThing and overloaded friends
        NamedThing(..),
-       isExported, 
        getSrcLoc, isLocallyDefined, getOccString
     ) where
 
        getSrcLoc, isLocallyDefined, getOccString
     ) where
 
@@ -44,8 +43,8 @@ import {-# SOURCE #-} Var   ( Id, setIdName )
 import {-# SOURCE #-} TyCon ( TyCon, setTyConName )
 
 import OccName         -- All of it
 import {-# SOURCE #-} TyCon ( TyCon, setTyConName )
 
 import OccName         -- All of it
-import Module
-import RdrName         ( RdrName, mkRdrQual, mkRdrUnqual )
+import Module          ( Module, moduleName, pprModule, mkVanillaModule )
+import RdrName         ( RdrName, mkRdrQual, mkRdrUnqual, rdrNameOcc, rdrNameModule )
 import CmdLineOpts     ( opt_PprStyle_NoPrags, opt_OmitInterfacePragmas, opt_EnsureSplittableC )
 
 import SrcLoc          ( noSrcLoc, mkBuiltinSrcLoc, SrcLoc )
 import CmdLineOpts     ( opt_PprStyle_NoPrags, opt_OmitInterfacePragmas, opt_EnsureSplittableC )
 
 import SrcLoc          ( noSrcLoc, mkBuiltinSrcLoc, SrcLoc )
@@ -109,6 +108,12 @@ mkGlobalName uniq mod occ prov = Name { n_uniq = uniq, n_sort = Global mod,
                                        n_occ = occ, n_prov = prov }
                                
 
                                        n_occ = occ, n_prov = prov }
                                
 
+mkKnownKeyGlobal :: (RdrName, Unique) -> Name
+mkKnownKeyGlobal (rdr_name, uniq)
+  = mkGlobalName uniq (mkVanillaModule (rdrNameModule rdr_name))
+                     (rdrNameOcc rdr_name)
+                     systemProvenance
+
 mkSysLocalName :: Unique -> FAST_STRING -> Name
 mkSysLocalName uniq fs = Name { n_uniq = uniq, n_sort = Local, 
                                n_occ = mkSrcVarOcc fs, n_prov = SystemProv }
 mkSysLocalName :: Unique -> FAST_STRING -> Name
 mkSysLocalName uniq fs = Name { n_uniq = uniq, n_sort = Local, 
                                n_occ = mkSrcVarOcc fs, n_prov = SystemProv }
@@ -213,9 +218,7 @@ are exported.  But also:
 \begin{code}
 tidyTopName :: Module -> TidyOccEnv -> Name -> (TidyOccEnv, Name)
 tidyTopName mod env name
 \begin{code}
 tidyTopName :: Module -> TidyOccEnv -> Name -> (TidyOccEnv, Name)
 tidyTopName mod env name
-  | isExported name = (env, name)      -- Don't fiddle with an exported name
-                                       -- It should be in the TidyOccEnv already
-  | otherwise       = (env', name')
+  = (env', name')
   where
     (env', occ') = tidyOccName env (n_occ name)
 
   where
     (env', occ') = tidyOccName env (n_occ name)
 
@@ -365,7 +368,7 @@ nameOccName         :: Name -> OccName
 nameModule             :: Name -> Module
 nameSrcLoc             :: Name -> SrcLoc
 isLocallyDefinedName   :: Name -> Bool
 nameModule             :: Name -> Module
 nameSrcLoc             :: Name -> SrcLoc
 isLocallyDefinedName   :: Name -> Bool
-isExportedName         :: Name -> Bool
+isUserExportedName     :: Name -> Bool
 isWiredInName          :: Name -> Bool
 isLocalName            :: Name -> Bool
 isGlobalName           :: Name -> Bool
 isWiredInName          :: Name -> Bool
 isLocalName            :: Name -> Bool
 isGlobalName           :: Name -> Bool
@@ -387,16 +390,16 @@ nameSortModule (WiredInTyCon mod _) = mod
 
 nameRdrName :: Name -> RdrName
 nameRdrName (Name { n_sort = Local, n_occ = occ }) = mkRdrUnqual occ
 
 nameRdrName :: Name -> RdrName
 nameRdrName (Name { n_sort = Local, n_occ = occ }) = mkRdrUnqual occ
-nameRdrName (Name { n_sort = sort,  n_occ = occ }) = mkRdrQual (nameSortModule sort) occ
+nameRdrName (Name { n_sort = sort,  n_occ = occ }) = mkRdrQual (moduleName (nameSortModule sort)) occ
 
 
-isExportedName (Name { n_prov = LocalDef _ Exported }) = True
-isExportedName other                                  = False
+isUserExportedName (Name { n_prov = LocalDef _ Exported }) = True
+isUserExportedName other                                  = False
 
 nameSrcLoc name = provSrcLoc (n_prov name)
 
 provSrcLoc (LocalDef loc _)                    = loc        
 provSrcLoc (NonLocalDef (UserImport _ loc _) _) = loc
 
 nameSrcLoc name = provSrcLoc (n_prov name)
 
 provSrcLoc (LocalDef loc _)                    = loc        
 provSrcLoc (NonLocalDef (UserImport _ loc _) _) = loc
-provSrcLoc SystemProv                          = noSrcLoc   
+provSrcLoc other                               = noSrcLoc   
   
 isLocallyDefinedName (Name {n_sort = Local})        = True     -- Local (might have SystemProv)
 isLocallyDefinedName (Name {n_prov = LocalDef _ _}) = True     -- Global, but defined here
   
 isLocallyDefinedName (Name {n_sort = Local})        = True     -- Local (might have SystemProv)
 isLocallyDefinedName (Name {n_prov = LocalDef _ _}) = True     -- Global, but defined here
@@ -517,7 +520,7 @@ pprName (Name {n_sort = sort, n_uniq = uniq, n_occ = occ, n_prov = prov})
 
     pp_mod_dot sty
       = case prov of
 
     pp_mod_dot sty
       = case prov of
-          SystemProv                                -> pp_qual mod  pp_sep    user_sty
+          SystemProv                                -> pp_qual mod user_sty
                -- Hack alert!  Omit the qualifier on SystemProv things in user style
                 -- I claim such SystemProv things will also be WiredIn things.
                -- We can't get the omit flag right
                -- Hack alert!  Omit the qualifier on SystemProv things in user style
                 -- I claim such SystemProv things will also be WiredIn things.
                -- We can't get the omit flag right
@@ -525,24 +528,20 @@ pprName (Name {n_sort = sort, n_uniq = uniq, n_occ = occ, n_prov = prov})
                -- and hope that leaving it out isn't too consfusing.
                -- (e.g. if the programmer hides Bool and  redefines it.  If so, use -dppr-debug.)
 
                -- and hope that leaving it out isn't too consfusing.
                -- (e.g. if the programmer hides Bool and  redefines it.  If so, use -dppr-debug.)
 
-          LocalDef _ _                              -> pp_qual mod  dot    (user_sty || iface_sty)
+          LocalDef _ _                              -> pp_qual mod (user_sty || iface_sty)
 
           NonLocalDef (UserImport imp_mod _ _) omit 
 
           NonLocalDef (UserImport imp_mod _ _) omit 
-               | user_sty                           -> pp_qual imp_mod pp_sep omit
-               | otherwise                          -> pp_qual mod     pp_sep False
-          NonLocalDef ImplicitImport           omit -> pp_qual mod     pp_sep (user_sty && omit)
+               | user_sty                           -> pp_qual imp_mod omit
+               | otherwise                          -> pp_qual mod     False
+          NonLocalDef ImplicitImport           omit -> pp_qual mod     (user_sty && omit)
       where
         user_sty  = userStyle sty
         iface_sty = ifaceStyle sty
     
       where
         user_sty  = userStyle sty
         iface_sty = ifaceStyle sty
     
-    pp_qual mod sep omit_qual
+    pp_qual mod omit_qual
         | omit_qual  = empty
         | omit_qual  = empty
-        | otherwise  = pprModule mod <> sep
+        | otherwise  = pprModule mod <> dot
     
     
-    pp_sep | bootFlavour (moduleIfaceFlavour mod) = text "!"   -- M!t indicates a name imported 
-                                                               -- from a .hi-boot interface
-          | otherwise                            = dot         -- Vanilla case
-   
     pp_global_debug sty uniq prov
       | debugStyle sty = hcat [text "{-", pprUnique uniq, prov_p prov, text "-}"]
       | otherwise      = empty
     pp_global_debug sty uniq prov
       | debugStyle sty = hcat [text "{-", pprUnique uniq, prov_p prov, text "-}"]
       | otherwise      = empty
@@ -576,10 +575,8 @@ class NamedThing a where
 \begin{code}
 getSrcLoc          :: NamedThing a => a -> SrcLoc
 isLocallyDefined    :: NamedThing a => a -> Bool
 \begin{code}
 getSrcLoc          :: NamedThing a => a -> SrcLoc
 isLocallyDefined    :: NamedThing a => a -> Bool
-isExported         :: NamedThing a => a -> Bool
 getOccString       :: NamedThing a => a -> String
 
 getOccString       :: NamedThing a => a -> String
 
-isExported         = isExportedName       . getName
 getSrcLoc          = nameSrcLoc           . getName
 isLocallyDefined    = isLocallyDefinedName . getName
 getOccString x     = occNameString (getOccName x)
 getSrcLoc          = nameSrcLoc           . getName
 isLocallyDefined    = isLocallyDefinedName . getName
 getOccString x     = occNameString (getOccName x)
index 0f857db..1c9d02b 100644 (file)
@@ -9,7 +9,7 @@ module NameSet (
        NameSet,
        emptyNameSet, unitNameSet, mkNameSet, unionNameSets, unionManyNameSets,
        minusNameSet, elemNameSet, nameSetToList, addOneToNameSet, addListToNameSet, 
        NameSet,
        emptyNameSet, unitNameSet, mkNameSet, unionNameSets, unionManyNameSets,
        minusNameSet, elemNameSet, nameSetToList, addOneToNameSet, addListToNameSet, 
-       delFromNameSet, delListFromNameSet, isEmptyNameSet,
+       delFromNameSet, delListFromNameSet, isEmptyNameSet, foldNameSet
     ) where
 
 #include "HsVersions.h"
     ) where
 
 #include "HsVersions.h"
@@ -40,6 +40,7 @@ nameSetToList    :: NameSet -> [Name]
 isEmptyNameSet    :: NameSet -> Bool
 delFromNameSet    :: NameSet -> Name -> NameSet
 delListFromNameSet :: NameSet -> [Name] -> NameSet
 isEmptyNameSet    :: NameSet -> Bool
 delFromNameSet    :: NameSet -> Name -> NameSet
 delListFromNameSet :: NameSet -> [Name] -> NameSet
+foldNameSet       :: (Name -> b -> b) -> b -> NameSet -> b
 
 isEmptyNameSet    = isEmptyUniqSet
 emptyNameSet     = emptyUniqSet
 
 isEmptyNameSet    = isEmptyUniqSet
 emptyNameSet     = emptyUniqSet
@@ -53,6 +54,7 @@ minusNameSet    = minusUniqSet
 elemNameSet       = elementOfUniqSet
 nameSetToList     = uniqSetToList
 delFromNameSet    = delOneFromUniqSet
 elemNameSet       = elementOfUniqSet
 nameSetToList     = uniqSetToList
 delFromNameSet    = delOneFromUniqSet
+foldNameSet      = foldUniqSet
 
 delListFromNameSet set ns = foldl delFromNameSet set ns
 \end{code}
 
 delListFromNameSet set ns = foldl delFromNameSet set ns
 \end{code}
index 838df14..3e5f52e 100644 (file)
@@ -28,10 +28,9 @@ import OccName       ( NameSpace, tcName,
                  mkSrcOccFS, mkSrcVarOcc,
                  isDataOcc, isTvOcc
                )
                  mkSrcOccFS, mkSrcVarOcc,
                  isDataOcc, isTvOcc
                )
-import Module   ( Module, IfaceFlavour, mkSysModuleFS,
-                 mkSrcModuleFS, pprModuleSep
+import Module   ( ModuleName,
+                 mkSysModuleFS, mkSrcModuleFS
                )
                )
-import PrelMods        ( pRELUDE )
 import Outputable
 import Util    ( thenCmp )
 \end{code}
 import Outputable
 import Util    ( thenCmp )
 \end{code}
@@ -47,7 +46,7 @@ import Util   ( thenCmp )
 data RdrName = RdrName Qual OccName
 
 data Qual = Unqual
 data RdrName = RdrName Qual OccName
 
 data Qual = Unqual
-         | Qual Module
+         | Qual ModuleName     -- The (encoded) module name
 \end{code}
 
 
 \end{code}
 
 
@@ -58,7 +57,7 @@ data Qual = Unqual
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
-rdrNameModule :: RdrName -> Module
+rdrNameModule :: RdrName -> ModuleName
 rdrNameModule (RdrName (Qual m) _) = m
 
 rdrNameOcc :: RdrName -> OccName
 rdrNameModule (RdrName (Qual m) _) = m
 
 rdrNameOcc :: RdrName -> OccName
@@ -70,13 +69,13 @@ rdrNameOcc (RdrName _ occ) = occ
 mkRdrUnqual :: OccName -> RdrName
 mkRdrUnqual occ = RdrName Unqual occ
 
 mkRdrUnqual :: OccName -> RdrName
 mkRdrUnqual occ = RdrName Unqual occ
 
-mkRdrQual :: Module -> OccName -> RdrName
+mkRdrQual :: ModuleName -> OccName -> RdrName
 mkRdrQual mod occ = RdrName (Qual mod) occ
 
        -- These two are used when parsing source files
        -- They do encode the module and occurrence names
 mkSrcUnqual :: NameSpace -> FAST_STRING -> RdrName
 mkRdrQual mod occ = RdrName (Qual mod) occ
 
        -- These two are used when parsing source files
        -- They do encode the module and occurrence names
 mkSrcUnqual :: NameSpace -> FAST_STRING -> RdrName
-mkSrcUnqual sp n   = RdrName Unqual (mkSrcOccFS sp n)
+mkSrcUnqual sp n = RdrName Unqual (mkSrcOccFS sp n)
 
 mkSrcQual :: NameSpace -> FAST_STRING -> FAST_STRING -> RdrName
 mkSrcQual sp m n = RdrName (Qual (mkSrcModuleFS m)) (mkSrcOccFS sp n)
 
 mkSrcQual :: NameSpace -> FAST_STRING -> FAST_STRING -> RdrName
 mkSrcQual sp m n = RdrName (Qual (mkSrcModuleFS m)) (mkSrcOccFS sp n)
@@ -84,15 +83,15 @@ mkSrcQual sp m n = RdrName (Qual (mkSrcModuleFS m)) (mkSrcOccFS sp n)
        -- These two are used when parsing interface files
        -- They do not encode the module and occurrence name
 mkSysUnqual :: NameSpace -> FAST_STRING -> RdrName
        -- These two are used when parsing interface files
        -- They do not encode the module and occurrence name
 mkSysUnqual :: NameSpace -> FAST_STRING -> RdrName
-mkSysUnqual sp n         = RdrName Unqual (mkSysOccFS sp n)
+mkSysUnqual sp n = RdrName Unqual (mkSysOccFS sp n)
 
 
-mkSysQual :: NameSpace -> (FAST_STRING, FAST_STRING, IfaceFlavour) -> RdrName
-mkSysQual sp (m,n,hif) = RdrName (Qual (mkSysModuleFS m hif)) (mkSysOccFS sp n)
+mkSysQual :: NameSpace -> (FAST_STRING, FAST_STRING) -> RdrName
+mkSysQual sp (m,n) = RdrName (Qual (mkSysModuleFS m)) (mkSysOccFS sp n)
 
 
-mkPreludeQual :: NameSpace -> Module -> FAST_STRING -> RdrName
+mkPreludeQual :: NameSpace -> ModuleName -> FAST_STRING -> RdrName
 mkPreludeQual sp mod n = RdrName (Qual mod) (mkSrcOccFS sp n)
 
 mkPreludeQual sp mod n = RdrName (Qual mod) (mkSrcOccFS sp n)
 
-qualifyRdrName :: Module -> RdrName -> RdrName
+qualifyRdrName :: ModuleName -> RdrName -> RdrName
 qualifyRdrName mod (RdrName Unqual occ) = RdrName (Qual mod) occ
 qualifyRdrName mod rdr_name            = rdr_name 
 \end{code}
 qualifyRdrName mod (RdrName Unqual occ) = RdrName (Qual mod) occ
 qualifyRdrName mod rdr_name            = rdr_name 
 \end{code}
@@ -130,7 +129,7 @@ instance Outputable RdrName where
     ppr (RdrName qual occ) = pp_qual qual <> ppr occ
                           where
                                pp_qual Unqual = empty
     ppr (RdrName qual occ) = pp_qual qual <> ppr occ
                           where
                                pp_qual Unqual = empty
-                               pp_qual (Qual mod) = ppr mod <> pprModuleSep mod
+                               pp_qual (Qual mod) = ppr mod <> dot
 
 instance Eq RdrName where
     a == b = case (a `compare` b) of { EQ -> True;  _ -> False }
 
 instance Eq RdrName where
     a == b = case (a `compare` b) of { EQ -> True;  _ -> False }
index 81e137d..ae87ce2 100644 (file)
@@ -152,6 +152,7 @@ module Unique (
        recSelErrIdKey,
        recUpdErrorIdKey,
        returnMClassOpKey,
        recSelErrIdKey,
        recUpdErrorIdKey,
        returnMClassOpKey,
+       runSTRepIdKey,
        showClassKey,
        ioTyConKey,
        ioDataConKey,
        showClassKey,
        ioTyConKey,
        ioDataConKey,
@@ -241,7 +242,9 @@ mkUniqueGrimily x = MkUnique x
 {-# INLINE getKey #-}
 getKey (MkUnique x) = x
 
 {-# INLINE getKey #-}
 getKey (MkUnique x) = x
 
-incrUnique (MkUnique i) = MkUnique (i +# 1#)
+incrUnique (MkUnique i) = MkUnique (i +# 100#)
+-- Bump the unique by a lot, to get it out of the neighbourhood
+-- of its friends
 
 -- pop the Char in the top 8 bits of the Unique(Supply)
 
 
 -- pop the Char in the top 8 bits of the Unique(Supply)
 
@@ -640,4 +643,5 @@ mapIdKey                  = mkPreludeMiscIdUnique 120
 
 \begin{code}
 assertIdKey                  = mkPreludeMiscIdUnique 121
 
 \begin{code}
 assertIdKey                  = mkPreludeMiscIdUnique 121
+runSTRepIdKey                = mkPreludeMiscIdUnique 122
 \end{code}
 \end{code}
index cacde2b..4d5be70 100644 (file)
@@ -5,10 +5,9 @@
 
 \begin{code}
 module Var (
 
 \begin{code}
 module Var (
-       Var, IdOrTyVar,         -- Abstract
-       VarDetails(..),         -- Concrete
-       varName, varUnique, varDetails, varInfo, varType,
-       setVarName, setVarUnique, setVarType,  setVarOcc,
+       Var, IdOrTyVar, VarDetails,             -- Abstract
+       varName, varUnique, varInfo, varType,
+       setVarName, setVarUnique, setVarType, setVarOcc,
 
 
        -- TyVars
 
 
        -- TyVars
@@ -26,18 +25,16 @@ module Var (
 
        -- Ids
        Id, DictId,
 
        -- Ids
        Id, DictId,
-       idDetails, idName, idType, idUnique, idInfo, modifyIdInfo,
+       idName, idType, idUnique, idInfo, modifyIdInfo, maybeModifyIdInfo,
        setIdName, setIdUnique, setIdInfo,
        setIdName, setIdUnique, setIdInfo,
-       mkId, isId, externallyVisibleId
+       mkIdVar, isId, externallyVisibleId
     ) where
 
 #include "HsVersions.h"
 
 import {-# SOURCE #-}  Type( Type, Kind )
 import {-# SOURCE #-}  IdInfo( IdInfo )
     ) where
 
 #include "HsVersions.h"
 
 import {-# SOURCE #-}  Type( Type, Kind )
 import {-# SOURCE #-}  IdInfo( IdInfo )
-import {-# SOURCE #-}  Const( Con )
 
 
-import FieldLabel      ( FieldLabel )
 import Unique          ( Unique, Uniquable(..), mkUniqueGrimily, getKey )
 import Name            ( Name, OccName, NamedThing(..),
                          setNameUnique, setNameOcc, nameUnique, 
 import Unique          ( Unique, Uniquable(..), mkUniqueGrimily, getKey )
 import Name            ( Name, OccName, NamedThing(..),
                          setNameUnique, setNameOcc, nameUnique, 
@@ -78,9 +75,7 @@ data Var
     }
 
 data VarDetails
     }
 
 data VarDetails
-  = VanillaId                          -- Most Ids are like this
-  | ConstantId Con                     -- The Id for a constant (data constructor or primop)
-  | RecordSelId FieldLabel             -- The Id for a record selector
+  = AnId
   | TyVar
   | MutTyVar (IORef (Maybe Type))      -- Used during unification;
             Bool                       -- True <=> this is a type signature variable, which
   | TyVar
   | MutTyVar (IORef (Maybe Type))      -- Used during unification;
             Bool                       -- True <=> this is a type signature variable, which
@@ -164,7 +159,7 @@ mkTyVar name kind = Var { varName    = name
                        , varType    = kind
                        , varDetails = TyVar
 #ifdef DEBUG
                        , varType    = kind
                        , varDetails = TyVar
 #ifdef DEBUG
-                       , varInfo = pprPanic "mkTyVar" (ppr name)
+                       , varInfo = pprPanic "looking at IdInfo of a tyvar" (ppr name)
 #endif
                        }
 
 #endif
                        }
 
@@ -264,7 +259,6 @@ idName    = varName
 idType    = varType
 idUnique  = varUnique
 idInfo   = varInfo
 idType    = varType
 idUnique  = varUnique
 idInfo   = varInfo
-idDetails = varDetails
 
 setIdUnique :: Id -> Unique -> Id
 setIdUnique = setVarUnique
 
 setIdUnique :: Id -> Unique -> Id
 setIdUnique = setVarUnique
@@ -275,24 +269,27 @@ setIdName = setVarName
 setIdInfo :: Id -> IdInfo -> Id
 setIdInfo var info = var {varInfo = info}
 
 setIdInfo :: Id -> IdInfo -> Id
 setIdInfo var info = var {varInfo = info}
 
-modifyIdInfo :: Id -> (IdInfo -> IdInfo) -> Id
-modifyIdInfo var@(Var {varInfo = info}) fn = var {varInfo = fn info}
+modifyIdInfo :: (IdInfo -> IdInfo) -> Id -> Id
+modifyIdInfo fn var@(Var {varInfo = info}) = var {varInfo = fn info}
+
+-- maybeModifyIdInfo tries to avoid unnecesary thrashing
+maybeModifyIdInfo :: (IdInfo -> Maybe IdInfo) -> Id -> Id
+maybeModifyIdInfo fn var@(Var {varInfo = info}) = case fn info of
+                                               Nothing       -> var
+                                               Just new_info -> var {varInfo = new_info}
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-mkId :: Name -> Type -> VarDetails -> IdInfo -> Id
-mkId name ty details info
+mkIdVar :: Name -> Type -> IdInfo -> Id
+mkIdVar name ty info
   = Var {varName = name, realUnique = getKey (nameUnique name), varType = ty, 
   = Var {varName = name, realUnique = getKey (nameUnique name), varType = ty, 
-        varDetails = details, varInfo = info}
+        varDetails = AnId, varInfo = info}
 \end{code}
 
 \begin{code}
 isId :: Var -> Bool
 \end{code}
 
 \begin{code}
 isId :: Var -> Bool
-isId (Var {varDetails = details}) = case details of
-                                       VanillaId     -> True
-                                       ConstantId _  -> True
-                                       RecordSelId _ -> True
-                                       other         -> False
+isId (Var {varDetails = AnId}) = True
+isId other                    = False
 \end{code}
 
 @externallyVisibleId@: is it true that another module might be
 \end{code}
 
 @externallyVisibleId@: is it true that another module might be
index db389ef..0b3d921 100644 (file)
@@ -16,11 +16,20 @@ module VarEnv (
        modifyVarEnv, modifyVarEnv_Directly,
        isEmptyVarEnv, foldVarEnv,
 
        modifyVarEnv, modifyVarEnv_Directly,
        isEmptyVarEnv, foldVarEnv,
 
-       TidyEnv, emptyTidyEnv
+       -- TidyEnvs
+       TidyEnv, emptyTidyEnv,
+
+       -- SubstEnvs
+       SubstEnv, TyVarSubstEnv, SubstResult(..), emptySubstEnv, 
+       mkSubstEnv, lookupSubstEnv, extendSubstEnv, extendSubstEnvList,
+       delSubstEnv, noTypeSubst, isEmptySubstEnv
     ) where
 
 #include "HsVersions.h"
 
     ) where
 
 #include "HsVersions.h"
 
+import {-# SOURCE #-}  CoreSyn( CoreExpr )
+import {-# SOURCE #-}  Type( Type )
+
 import OccName ( TidyOccEnv, emptyTidyOccEnv )
 import Var     ( Var, Id, IdOrTyVar )
 import UniqFM
 import OccName ( TidyOccEnv, emptyTidyOccEnv )
 import Var     ( Var, Id, IdOrTyVar )
 import UniqFM
@@ -45,6 +54,55 @@ emptyTidyEnv = (emptyTidyOccEnv, emptyVarEnv)
 
 %************************************************************************
 %*                                                                     *
 
 %************************************************************************
 %*                                                                     *
+\subsection{Substitution environments}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+
+noTys :: SubstResult -> Bool -> Bool
+noTys (DoneTy ty) no_tys = False
+noTys other      no_tys = no_tys
+
+data SubstEnv      = SE (VarEnv SubstResult)
+                       Bool            -- True => definitely no type substitutions in the env
+
+noTypeSubst :: SubstEnv -> Bool
+noTypeSubst (SE _ nt) = nt
+
+type TyVarSubstEnv = SubstEnv  -- of the form (DoneTy ty) *only*
+
+data SubstResult
+  = DoneEx CoreExpr            -- Completed term
+  | DoneTy Type                        -- Completed type
+  | ContEx SubstEnv CoreExpr   -- A suspended substitution
+
+emptySubstEnv :: SubstEnv
+emptySubstEnv = SE emptyVarEnv True
+
+isEmptySubstEnv :: SubstEnv -> Bool
+isEmptySubstEnv (SE s _) = isEmptyVarEnv s
+
+lookupSubstEnv :: SubstEnv -> Var -> Maybe SubstResult
+lookupSubstEnv (SE s _) v = lookupVarEnv s v
+
+extendSubstEnv :: SubstEnv -> Var -> SubstResult -> SubstEnv
+extendSubstEnv (SE s nt) v r = SE (extendVarEnv s v r) (noTys r nt)
+
+mkSubstEnv :: [IdOrTyVar] -> [SubstResult] -> SubstEnv
+mkSubstEnv bs vs = extendSubstEnvList emptySubstEnv bs vs
+
+extendSubstEnvList :: SubstEnv -> [IdOrTyVar] -> [SubstResult] -> SubstEnv
+extendSubstEnvList env        []     []     = env
+extendSubstEnvList (SE env nt) (b:bs) (r:rs) = extendSubstEnvList (SE (extendVarEnv env b r) (noTys r nt)) bs rs
+
+delSubstEnv :: SubstEnv -> IdOrTyVar -> SubstEnv
+delSubstEnv (SE s nt) v = SE (delVarEnv s v) nt
+\end{code}
+
+
+%************************************************************************
+%*                                                                     *
 \subsection{@VarEnv@s}
 %*                                                                     *
 %************************************************************************
 \subsection{@VarEnv@s}
 %*                                                                     *
 %************************************************************************
index 9091dfe..fb5b6cf 100644 (file)
@@ -8,10 +8,10 @@ module VarSet (
        VarSet, IdSet, TyVarSet, IdOrTyVarSet,
        emptyVarSet, unitVarSet, mkVarSet,
        extendVarSet,
        VarSet, IdSet, TyVarSet, IdOrTyVarSet,
        emptyVarSet, unitVarSet, mkVarSet,
        extendVarSet,
-       elemVarSet, varSetElems,
+       elemVarSet, varSetElems, subVarSet,
        unionVarSet, unionVarSets,
        intersectVarSet, intersectsVarSet,
        unionVarSet, unionVarSets,
        intersectVarSet, intersectsVarSet,
-       isEmptyVarSet, delVarSet,
+       isEmptyVarSet, delVarSet, delVarSetByKey,
        minusVarSet, foldVarSet, filterVarSet,
        lookupVarSet, mapVarSet,
 
        minusVarSet, foldVarSet, filterVarSet,
        lookupVarSet, mapVarSet,
 
@@ -20,9 +20,11 @@ module VarSet (
 
 #include "HsVersions.h"
 
 
 #include "HsVersions.h"
 
+import CmdLineOpts     ( opt_PprStyle_Debug )
 import Var             ( Var, Id, TyVar, IdOrTyVar, setVarUnique )
 import Var             ( Var, Id, TyVar, IdOrTyVar, setVarUnique )
-import Unique          ( Uniquable(..), incrUnique )
+import Unique          ( Unique, Uniquable(..), incrUnique )
 import UniqSet
 import UniqSet
+import UniqFM          ( delFromUFM_Directly )
 import Outputable
 \end{code}
 
 import Outputable
 \end{code}
 
@@ -57,6 +59,9 @@ lookupVarSet  :: VarSet -> Var -> Maybe Var
                        -- (==) to the argument, but not the same as
 mapVarSet      :: (Var -> Var) -> VarSet -> VarSet
 filterVarSet   :: (Var -> Bool) -> VarSet -> VarSet
                        -- (==) to the argument, but not the same as
 mapVarSet      :: (Var -> Var) -> VarSet -> VarSet
 filterVarSet   :: (Var -> Bool) -> VarSet -> VarSet
+subVarSet      :: VarSet -> VarSet -> Bool
+
+delVarSetByKey :: VarSet -> Unique -> VarSet
 
 emptyVarSet    = emptyUniqSet
 unitVarSet     = unitUniqSet
 
 emptyVarSet    = emptyUniqSet
 unitVarSet     = unitUniqSet
@@ -75,15 +80,24 @@ foldVarSet  = foldUniqSet
 lookupVarSet   = lookupUniqSet
 mapVarSet      = mapUniqSet
 filterVarSet   = filterUniqSet
 lookupVarSet   = lookupUniqSet
 mapVarSet      = mapUniqSet
 filterVarSet   = filterUniqSet
+a `subVarSet` b = isEmptyVarSet (a `minusVarSet` b)
+delVarSetByKey = delFromUFM_Directly   -- Can't be bothered to add this to UniqSet
 \end{code}
 
 \begin{code}
 uniqAway :: VarSet -> Var -> Var
 -- Give the Var a new unique, different to any in the VarSet
 uniqAway set var
 \end{code}
 
 \begin{code}
 uniqAway :: VarSet -> Var -> Var
 -- Give the Var a new unique, different to any in the VarSet
 uniqAway set var
+  | not (var `elemVarSet` set) = var   -- Nothing to do
+
+  | otherwise
   = try 1 (incrUnique (getUnique var))
   where
     try n uniq | uniq `elemUniqSet_Directly` set = try ((n+1)::Int) (incrUnique uniq)
   = try 1 (incrUnique (getUnique var))
   where
     try n uniq | uniq `elemUniqSet_Directly` set = try ((n+1)::Int) (incrUnique uniq)
-              | otherwise = {- pprTrace "uniqAway:" (ppr n <+> text "tries") -}
-                            setVarUnique var uniq
+#ifdef DEBUG
+              | opt_PprStyle_Debug && n > 3
+              = pprTrace "uniqAway:" (ppr n <+> text "tries" <+> ppr var) 
+                setVarUnique var uniq
+#endif                     
+              | otherwise = setVarUnique var uniq
 \end{code}
 \end{code}
index aa09d5d..b02e248 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: CgCase.lhs,v 1.28 1999/05/13 17:30:55 simonm Exp $
+% $Id: CgCase.lhs,v 1.29 1999/05/18 15:03:46 simonpj Exp $
 %
 %********************************************************
 %*                                                     *
 %
 %********************************************************
 %*                                                     *
@@ -11,8 +11,8 @@
 
 \begin{code}
 module CgCase (        cgCase, saveVolatileVarsAndRegs, 
 
 \begin{code}
 module CgCase (        cgCase, saveVolatileVarsAndRegs, 
-               restoreCurrentCostCentre, freeCostCentreSlot,
-               splitTyConAppThroughNewTypes ) where
+               restoreCurrentCostCentre, freeCostCentreSlot
+       ) where
 
 #include "HsVersions.h"
 
 
 #include "HsVersions.h"
 
@@ -25,7 +25,6 @@ import AbsCSyn
 import AbsCUtils       ( mkAbstractCs, mkAbsCStmts, mkAlgAltsCSwitch,
                          getAmodeRep, nonemptyAbsC
                        )
 import AbsCUtils       ( mkAbstractCs, mkAbsCStmts, mkAlgAltsCSwitch,
                          getAmodeRep, nonemptyAbsC
                        )
-import CoreSyn         ( isDeadBinder )
 import CgUpdate                ( reserveSeqFrame )
 import CgBindery       ( getVolatileRegs, getArgAmodes, getArgAmode,
                          bindNewToReg, bindNewToTemp,
 import CgUpdate                ( reserveSeqFrame )
 import CgBindery       ( getVolatileRegs, getArgAmodes, getArgAmode,
                          bindNewToReg, bindNewToTemp,
@@ -51,6 +50,7 @@ import CLabel         ( CLabel, mkVecTblLabel, mkReturnPtLabel,
 import ClosureInfo     ( mkLFArgument )
 import CmdLineOpts     ( opt_SccProfilingOn, opt_GranMacros )
 import CostCentre      ( CostCentre )
 import ClosureInfo     ( mkLFArgument )
 import CmdLineOpts     ( opt_SccProfilingOn, opt_GranMacros )
 import CostCentre      ( CostCentre )
+import CoreSyn         ( isDeadBinder )
 import Id              ( Id, idPrimRep )
 import DataCon         ( DataCon, dataConTag, fIRST_TAG, ConTag,
                          isUnboxedTupleCon, dataConType )
 import Id              ( Id, idPrimRep )
 import DataCon         ( DataCon, dataConTag, fIRST_TAG, ConTag,
                          isUnboxedTupleCon, dataConType )
@@ -63,8 +63,7 @@ import TyCon          ( TyCon, isEnumerationTyCon, isUnboxedTupleTyCon,
                          isNewTyCon, isAlgTyCon, isFunTyCon, isPrimTyCon,
                          tyConDataCons, tyConFamilySize )
 import Type            ( Type, typePrimRep, splitAlgTyConApp, 
                          isNewTyCon, isAlgTyCon, isFunTyCon, isPrimTyCon,
                          tyConDataCons, tyConFamilySize )
 import Type            ( Type, typePrimRep, splitAlgTyConApp, 
-                         splitTyConApp_maybe,
-                          splitFunTys, applyTys )
+                         splitTyConApp_maybe, splitRepTyConApp_maybe )
 import Unique           ( Unique, Uniquable(..), mkBuiltinUnique )
 import Maybes          ( maybeToBool )
 import Util
 import Unique           ( Unique, Uniquable(..), mkBuiltinUnique )
 import Maybes          ( maybeToBool )
 import Util
@@ -238,10 +237,8 @@ cgCase (StgApp v []) live_in_whole_case live_in_alts bndr srt
        two bindings pointing at the same stack locn doesn't work (it
        confuses nukeDeadBindings).  Hence, use a new temp.
     -}
        two bindings pointing at the same stack locn doesn't work (it
        confuses nukeDeadBindings).  Hence, use a new temp.
     -}
-    (if (isDeadBinder bndr)
-       then nopC
-       else bindNewToTemp bndr  `thenFC`  \deflt_amode ->
-            absC (CAssign deflt_amode amode)) `thenC`
+    bindNewToTemp bndr                 `thenFC`  \deflt_amode ->
+    absC (CAssign deflt_amode amode)   `thenC`
 
     cgPrimAlts NoGC amode alts deflt []
 \end{code}
 
     cgPrimAlts NoGC amode alts deflt []
 \end{code}
@@ -448,9 +445,7 @@ cgEvalAlts cc_slot bndr srt alts
       (StgAlgAlts ty alts deflt) ->
 
           -- bind the default binder (it covers all the alternatives)
       (StgAlgAlts ty alts deflt) ->
 
           -- bind the default binder (it covers all the alternatives)
-       (if (isDeadBinder bndr)
-               then nopC
-               else bindNewToReg bndr node mkLFArgument) `thenC`
+       bindNewToReg bndr node mkLFArgument      `thenC`
 
        -- Generate sequel info for use downstream
        -- At the moment, we only do it if the type is vector-returnable.
 
        -- Generate sequel info for use downstream
        -- At the moment, we only do it if the type is vector-returnable.
@@ -757,9 +752,7 @@ cgPrimEvalAlts bndr ty alts deflt
 
 cgPrimAltsWithDefault bndr gc_flag scrutinee alts deflt regs
   =    -- first bind the default if necessary
 
 cgPrimAltsWithDefault bndr gc_flag scrutinee alts deflt regs
   =    -- first bind the default if necessary
-    (if isDeadBinder bndr 
-       then nopC
-       else bindNewPrimToAmode bndr scrutinee)         `thenC`
+    bindNewPrimToAmode bndr scrutinee          `thenC`
     cgPrimAlts gc_flag scrutinee alts deflt regs
 
 cgPrimAlts gc_flag scrutinee alts deflt regs
     cgPrimAlts gc_flag scrutinee alts deflt regs
 
 cgPrimAlts gc_flag scrutinee alts deflt regs
@@ -988,41 +981,14 @@ possibleHeapCheck NoGC    _ _ tags lbl code
   = code
 \end{code}
 
   = code
 \end{code}
 
-splitTyConAppThroughNewTypes is like splitTyConApp_maybe except
-that it looks through newtypes in addition to synonyms.  It's
-useful in the back end where we're not interested in newtypes
-anymore.
-
-Sometimes, we've thrown away the constructors during pruning in the
-renamer.  In these cases, we emit a warning and fall back to using a
-SEQ_FRAME to evaluate the case scrutinee.
-
 \begin{code}
 getScrutineeTyCon :: Type -> Maybe TyCon
 getScrutineeTyCon ty =
 \begin{code}
 getScrutineeTyCon :: Type -> Maybe TyCon
 getScrutineeTyCon ty =
-   case (splitTyConAppThroughNewTypes ty) of
+   case splitRepTyConApp_maybe ty of
        Nothing -> Nothing
        Just (tc,_) -> 
                if isFunTyCon tc  then Nothing else     -- not interested in funs
                if isPrimTyCon tc then Just tc else     -- return primitive tycons
                        -- otherwise (algebraic tycons) check the no. of constructors
        Nothing -> Nothing
        Just (tc,_) -> 
                if isFunTyCon tc  then Nothing else     -- not interested in funs
                if isPrimTyCon tc then Just tc else     -- return primitive tycons
                        -- otherwise (algebraic tycons) check the no. of constructors
-               case (tyConFamilySize tc) of
-                       0 -> pprTrace "Warning" (hcat [
-                               text "constructors for ",
-                               ppr tc,
-                               text " not available.\n\tUse -fno-prune-tydecls to fix."
-                               ]) Nothing
-                       _ -> Just tc
-
-splitTyConAppThroughNewTypes  :: Type -> Maybe (TyCon, [Type])
-splitTyConAppThroughNewTypes ty
-  = case splitTyConApp_maybe ty of
-      Just (tc, tys)
-       | isNewTyCon tc ->  splitTyConAppThroughNewTypes ty
-       | otherwise     ->  Just (tc, tys)
-       where
-         ([ty], _) = splitFunTys (applyTys (dataConType (head (tyConDataCons tc))) tys)
-
-      other  -> Nothing
-
+               Just tc
 \end{code}
 \end{code}
index edcb089..7d532ba 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: CgClosure.lhs,v 1.30 1999/05/13 17:30:56 simonm Exp $
+% $Id: CgClosure.lhs,v 1.31 1999/05/18 15:03:47 simonpj Exp $
 %
 \section[CgClosure]{Code generation for closures}
 
 %
 \section[CgClosure]{Code generation for closures}
 
@@ -22,7 +22,6 @@ import {-# SOURCE #-} CgExpr ( cgExpr )
 import CgMonad
 import AbsCSyn
 import StgSyn
 import CgMonad
 import AbsCSyn
 import StgSyn
-import BasicTypes      ( TopLevelFlag(..) )
 
 import AbsCUtils       ( mkAbstractCs, getAmodeRep )
 import CgBindery       ( getCAddrMode, getArgAmodes,
 
 import AbsCUtils       ( mkAbstractCs, getAmodeRep )
 import CgBindery       ( getCAddrMode, getArgAmodes,
index 35dcdc2..6be1371 100644 (file)
@@ -50,7 +50,6 @@ import Module         ( isDynamicModule )
 import Const           ( Con(..), Literal(..), isLitLitLit )
 import PrelInfo                ( maybeCharLikeCon, maybeIntLikeCon )
 import PrimRep         ( PrimRep(..) )
 import Const           ( Con(..), Literal(..), isLitLitLit )
 import PrelInfo                ( maybeCharLikeCon, maybeIntLikeCon )
 import PrimRep         ( PrimRep(..) )
-import BasicTypes      ( TopLevelFlag(..) )
 import Util
 import Panic           ( assertPanic, trace )
 \end{code}
 import Util
 import Panic           ( assertPanic, trace )
 \end{code}
index 99d286e..6b75ee5 100644 (file)
@@ -26,7 +26,6 @@ import Name           ( getOccString )
 import PrimRep         ( getPrimRepSize, PrimRep(..) )
 import TyCon           ( tyConDataCons, isEnumerationTyCon, TyCon )
 import Type            ( typePrimRep, Type )
 import PrimRep         ( getPrimRepSize, PrimRep(..) )
 import TyCon           ( tyConDataCons, isEnumerationTyCon, TyCon )
 import Type            ( typePrimRep, Type )
-import BasicTypes      ( TopLevelFlag(..) )
 import Outputable      
 \end{code}
 
 import Outputable      
 \end{code}
 
@@ -72,15 +71,10 @@ closures predeclared.
 \begin{code}
 genStaticConBits :: CompilationInfo    -- global info about the compilation
                 -> [TyCon]             -- tycons to generate
 \begin{code}
 genStaticConBits :: CompilationInfo    -- global info about the compilation
                 -> [TyCon]             -- tycons to generate
-                -> FiniteMap TyCon [(Bool, [Maybe Type])]
-                                       -- tycon specialisation info
                 -> AbstractC           -- output
 
                 -> AbstractC           -- output
 
-genStaticConBits comp_info gen_tycons tycon_specs
-  = ASSERT( null (fmToList tycon_specs) )
-       -- We don't do specialised type constructors any more
-
-    -- for each type constructor:
+genStaticConBits comp_info gen_tycons
+  = -- for each type constructor:
     --  grab all its data constructors;
     --     for each one, generate an info table
     -- for each specialised type constructor
     --  grab all its data constructors;
     --     for each one, generate an info table
     -- for each specialised type constructor
index 5c4cd9b..4490a81 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: CgExpr.lhs,v 1.24 1999/05/07 13:44:00 simonm Exp $
+% $Id: CgExpr.lhs,v 1.25 1999/05/18 15:03:49 simonpj Exp $
 %
 %********************************************************
 %*                                                     *
 %
 %********************************************************
 %*                                                     *
@@ -24,8 +24,7 @@ import CLabel         ( mkClosureTblLabel )
 import SMRep           ( fixedHdrSize )
 import CgBindery       ( getArgAmodes, getArgAmode, CgIdInfo, nukeDeadBindings)
 import CgCase          ( cgCase, saveVolatileVarsAndRegs, 
 import SMRep           ( fixedHdrSize )
 import CgBindery       ( getArgAmodes, getArgAmode, CgIdInfo, nukeDeadBindings)
 import CgCase          ( cgCase, saveVolatileVarsAndRegs, 
-                         restoreCurrentCostCentre, freeCostCentreSlot,
-                         splitTyConAppThroughNewTypes )
+                         restoreCurrentCostCentre, freeCostCentreSlot )
 import CgClosure       ( cgRhsClosure, cgStdRhsClosure )
 import CgCon           ( buildDynCon, cgReturnDataCon )
 import CgLetNoEscape   ( cgLetNoEscapeClosure )
 import CgClosure       ( cgRhsClosure, cgStdRhsClosure )
 import CgCon           ( buildDynCon, cgReturnDataCon )
 import CgLetNoEscape   ( cgLetNoEscapeClosure )
@@ -48,7 +47,7 @@ import PrimOp         ( primOpOutOfLine,
 import PrimRep         ( getPrimRepSize, PrimRep(..), isFollowableRep )
 import TyCon           ( maybeTyConSingleCon,
                          isUnboxedTupleTyCon, isEnumerationTyCon )
 import PrimRep         ( getPrimRepSize, PrimRep(..), isFollowableRep )
 import TyCon           ( maybeTyConSingleCon,
                          isUnboxedTupleTyCon, isEnumerationTyCon )
-import Type            ( Type, typePrimRep, splitTyConApp_maybe )
+import Type            ( Type, typePrimRep, splitTyConApp_maybe, splitRepTyConApp_maybe )
 import Maybes          ( assocMaybe, maybeToBool )
 import Unique          ( mkBuiltinUnique )
 import BasicTypes      ( TopLevelFlag(..), RecFlag(..) )
 import Maybes          ( assocMaybe, maybeToBool )
 import Unique          ( mkBuiltinUnique )
 import BasicTypes      ( TopLevelFlag(..), RecFlag(..) )
@@ -463,7 +462,7 @@ primRetUnboxedTuple op args res_ty
       allocate some temporaries for the return values.
     -}
     let
       allocate some temporaries for the return values.
     -}
     let
-      (tc,ty_args)      = case splitTyConAppThroughNewTypes res_ty of
+      (tc,ty_args)      = case splitRepTyConApp_maybe res_ty of
                            Nothing -> pprPanic "primRetUnboxedTuple" (ppr res_ty)
                            Just pr -> pr
       prim_reps          = map typePrimRep ty_args
                            Nothing -> pprPanic "primRetUnboxedTuple" (ppr res_ty)
                            Just pr -> pr
       prim_reps          = map typePrimRep ty_args
index dea30bf..06a9a52 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: CgMonad.lhs,v 1.19 1999/05/13 17:30:57 simonm Exp $
+% $Id: CgMonad.lhs,v 1.20 1999/05/18 15:03:49 simonpj Exp $
 %
 \section[CgMonad]{The code generation monad}
 
 %
 \section[CgMonad]{The code generation monad}
 
@@ -29,7 +29,7 @@ module CgMonad (
 
        StackUsage, HeapUsage,
 
 
        StackUsage, HeapUsage,
 
-       profCtrC,
+       profCtrC, cgPanic,
 
        costCentresC, moduleName,
 
 
        costCentresC, moduleName,
 
@@ -49,7 +49,7 @@ import {-# SOURCE #-} CgUsages  ( getSpRelOffset )
 import AbsCSyn
 import AbsCUtils       ( mkAbsCStmts )
 import CmdLineOpts     ( opt_SccProfilingOn, opt_DoTickyProfiling )
 import AbsCSyn
 import AbsCUtils       ( mkAbsCStmts )
 import CmdLineOpts     ( opt_SccProfilingOn, opt_DoTickyProfiling )
-import CLabel           ( CLabel, mkUpdInfoLabel )
+import CLabel           ( CLabel, mkUpdInfoLabel, pprCLabel )
 import Module          ( Module )
 import DataCon         ( ConTag )
 import Id              ( Id )
 import Module          ( Module )
 import DataCon         ( ConTag )
 import Id              ( Id )
@@ -177,7 +177,7 @@ sequelToAmode (OnStack virt_sp_offset)
 
 sequelToAmode UpdateCode = returnFC (CLbl mkUpdInfoLabel RetRep)
 sequelToAmode (CaseAlts amode _) = returnFC amode
 
 sequelToAmode UpdateCode = returnFC (CLbl mkUpdInfoLabel RetRep)
 sequelToAmode (CaseAlts amode _) = returnFC amode
-sequelToAmode (SeqFrame _ _) = panic "sequelToAmode: SeqFrame"
+sequelToAmode (SeqFrame _ _) = cgPanic (text "sequelToAmode: SeqFrame")
 
 type CgStksAndHeapUsage                -- stacks and heap usage information
   = (StackUsage, HeapUsage)
 
 type CgStksAndHeapUsage                -- stacks and heap usage information
   = (StackUsage, HeapUsage)
@@ -608,13 +608,17 @@ lookupBindC name info_down@(MkCgInfoDown _ static_binds srt _)
       case (lookupVarEnv static_binds name) of
        Just this -> this
        Nothing
       case (lookupVarEnv static_binds name) of
        Just this -> this
        Nothing
-         -> pprPanic "lookupBindC:no info!\n"
-            (vcat [
-               hsep [ptext SLIT("for:"), ppr name],
-               ptext SLIT("(probably: data dependencies broken by an optimisation pass)"),
+         -> cgPanic (text "lookupBindC: no info for" <+> ppr name) info_down state
+
+cgPanic :: SDoc -> CgInfoDownwards -> CgState -> a
+cgPanic doc info_down@(MkCgInfoDown _ static_binds srt _)
+           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:"),
                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 ]
+               vcat [ ppr i | (MkCgIdInfo i _ _ _) <- rngVarEnv local_binds ],
+               ptext SLIT("SRT label") <+> pprCLabel srt
              ])
 \end{code}
              ])
 \end{code}
index 986bfd2..3b7b5a1 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: ClosureInfo.lhs,v 1.37 1999/05/11 16:44:02 keithw Exp $
+% $Id: ClosureInfo.lhs,v 1.38 1999/05/18 15:03:50 simonpj Exp $
 %
 \section[ClosureInfo]{Data structures which describe closures}
 
 %
 \section[ClosureInfo]{Data structures which describe closures}
 
@@ -88,7 +88,7 @@ import PprType                ( getTyDescription )
 import PrimRep         ( getPrimRepSize, separateByPtrFollowness, PrimRep )
 import SMRep           -- all of it
 import Type            ( isUnLiftedType, Type )
 import PrimRep         ( getPrimRepSize, separateByPtrFollowness, PrimRep )
 import SMRep           -- all of it
 import Type            ( isUnLiftedType, Type )
-import BasicTypes      ( TopLevelFlag(..) )
+import BasicTypes      ( TopLevelFlag(..), isNotTopLevel, isTopLevel )
 import Util            ( mapAccumL )
 import Outputable
 \end{code}
 import Util            ( mapAccumL )
 import Outputable
 \end{code}
@@ -543,7 +543,7 @@ nodeMustPointToIt lf_info
   = case lf_info of
        LFReEntrant ty top arity no_fvs _ _ -> returnFC (
            not no_fvs ||   -- Certainly if it has fvs we need to point to it
   = case lf_info of
        LFReEntrant ty top arity no_fvs _ _ -> returnFC (
            not no_fvs ||   -- Certainly if it has fvs we need to point to it
-           case top of { TopLevel -> False; _ -> True }
+           isNotTopLevel top
                    -- If it is not top level we will point to it
                    --   We can have a \r closure with no_fvs which
                    --   is not top level as special case cgRhsClosure
                    -- If it is not top level we will point to it
                    --   We can have a \r closure with no_fvs which
                    --   is not top level as special case cgRhsClosure
@@ -835,7 +835,7 @@ staticClosureRequired
        -> Bool
 staticClosureRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
                      (LFReEntrant _ top_level _ _ _ _) -- It's a function
        -> Bool
 staticClosureRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
                      (LFReEntrant _ top_level _ _ _ _) -- It's a function
-  = ASSERT( case top_level of { TopLevel -> True; other -> False } )
+  = ASSERT( isTopLevel top_level )
        -- Assumption: it's a top-level, no-free-var binding
     arg_occ            -- There's an argument occurrence
     || unsat_occ       -- There's an unsaturated call
        -- Assumption: it's a top-level, no-free-var binding
     arg_occ            -- There's an argument occurrence
     || unsat_occ       -- There's an unsaturated call
@@ -865,7 +865,7 @@ funInfoTableRequired
        -> Bool
 funInfoTableRequired  binder (StgBinderInfo arg_occ unsat_occ _ _ _)
                     (LFReEntrant _ top_level _ _ _ _)
        -> Bool
 funInfoTableRequired  binder (StgBinderInfo arg_occ unsat_occ _ _ _)
                     (LFReEntrant _ top_level _ _ _ _)
-  = (case top_level of { NotTopLevel -> True; TopLevel -> False })
+  =    isNotTopLevel top_level
     || arg_occ                 -- There's an argument occurrence
     || unsat_occ       -- There's an unsaturated call
     || isExternallyVisibleName binder
     || arg_occ                 -- There's an argument occurrence
     || unsat_occ       -- There's an unsaturated call
     || isExternallyVisibleName binder
index c6d94f4..35e18cb 100644 (file)
@@ -24,73 +24,90 @@ import CgMonad
 import AbsCSyn
 import CLabel          ( CLabel, mkSRTLabel, mkClosureLabel )
 
 import AbsCSyn
 import CLabel          ( CLabel, mkSRTLabel, mkClosureLabel )
 
-import AbsCUtils       ( mkAbstractCs, mkAbsCStmts )
+import PprAbsC         ( dumpRealC )
+import AbsCUtils       ( mkAbstractCs, mkAbsCStmts, flattenAbsC )
 import CgBindery       ( CgIdInfo )
 import CgClosure       ( cgTopRhsClosure )
 import CgCon           ( cgTopRhsCon )
 import CgConTbls       ( genStaticConBits )
 import ClosureInfo     ( mkClosureLFInfo )
 import CmdLineOpts     ( opt_SccProfilingOn, opt_EnsureSplittableC, 
 import CgBindery       ( CgIdInfo )
 import CgClosure       ( cgTopRhsClosure )
 import CgCon           ( cgTopRhsCon )
 import CgConTbls       ( genStaticConBits )
 import ClosureInfo     ( mkClosureLFInfo )
 import CmdLineOpts     ( opt_SccProfilingOn, opt_EnsureSplittableC, 
-                                             opt_SccGroup
+                         opt_D_dump_absC,    opt_SccGroup
                        )
 import CostCentre       ( CostCentre, CostCentreStack )
 import FiniteMap       ( FiniteMap )
 import Id               ( Id, idName )
                        )
 import CostCentre       ( CostCentre, CostCentreStack )
 import FiniteMap       ( FiniteMap )
 import Id               ( Id, idName )
-import Module           ( Module, moduleString )
+import Module           ( Module, moduleString, ModuleName, moduleNameString )
 import PrimRep         ( getPrimRepSize, PrimRep(..) )
 import Type             ( Type )
 import PrimRep         ( getPrimRepSize, PrimRep(..) )
 import Type             ( Type )
-import TyCon            ( TyCon )
+import TyCon            ( TyCon, isDataTyCon )
+import Class           ( Class, classTyCon )
 import BasicTypes      ( TopLevelFlag(..) )
 import BasicTypes      ( TopLevelFlag(..) )
+import UniqSupply      ( mkSplitUniqSupply )
+import ErrUtils                ( dumpIfSet )
 import Util
 import Panic           ( assertPanic )
 \end{code}
 
 \begin{code}
 import Util
 import Panic           ( assertPanic )
 \end{code}
 
 \begin{code}
-codeGen :: Module              -- module name
-       -> ([CostCentre],       -- local cost-centres needing declaring/registering
+
+
+codeGen :: Module              -- Module name
+       -> [ModuleName]         -- Import names
+       -> ([CostCentre],       -- Local cost-centres needing declaring/registering
            [CostCentre],       -- "extern" cost-centres needing declaring
            [CostCentre],       -- "extern" cost-centres needing declaring
-           [CostCentreStack])  -- pre-defined "singleton" cost centre stacks
-       -> [Module]             -- import names
-       -> [TyCon]              -- tycons with data constructors to convert
-       -> FiniteMap TyCon [(Bool, [Maybe Type])]
-                               -- tycon specialisation info
-       -> [(StgBinding,[Id])]  -- bindings to convert, with SRTs
-       -> AbstractC            -- output
-
-codeGen mod_name (local_CCs, extern_CCs, singleton_CCSs) 
-       import_names gen_tycons tycon_specs stg_pgm
-  = let
-       maybe_split       = if opt_EnsureSplittableC 
-                               then CSplitMarker 
-                               else AbsCNop
-       cinfo             = MkCompInfo mod_name
+           [CostCentreStack])  -- Pre-defined "singleton" cost centre stacks
+       -> [TyCon] -> [Class]   -- Local tycons and classes
+       -> [(StgBinding,[Id])]  -- Bindings to convert, with SRTs
+       -> IO AbstractC         -- Output
+
+codeGen mod_name imported_modules cost_centre_info
+       tycons classes stg_binds
+  = mkSplitUniqSupply 'f'      >>= \ fl_uniqs  -> -- absC flattener
+    let
+       datatype_stuff    = genStaticConBits cinfo data_tycons
+       code_stuff        = initC cinfo (cgTopBindings maybe_split stg_binds)
+       cost_centre_stuff = mkCostCentreStuff mod_name imported_modules cost_centre_info
+
+       abstractC = mkAbstractCs [ cost_centre_stuff, 
+                                  datatype_stuff,
+                                  code_stuff ]
+
+       flat_abstractC = flattenAbsC fl_uniqs abstractC
     in
     in
-    let 
-       module_code = mkAbstractCs [
-           genStaticConBits cinfo gen_tycons tycon_specs,
-           initC cinfo (cgTopBindings maybe_split stg_pgm) ]
-
-        -- Cost-centre profiling:
-        -- Besides the usual stuff, we must produce:
-        --
-        -- * Declarations for the cost-centres defined in this module;
-        -- * Code to participate in "registering" all the cost-centres
-        --   in the program (done at startup time when the pgm is run).
-        --
-        -- (The local cost-centres involved in this are passed
-        -- into the code-generator, as are the imported-modules' names.)
-        --
-        --
-       cost_centre_stuff 
-               | not opt_SccProfilingOn = AbsCNop
-               | otherwise = mkAbstractCs (
+    dumpIfSet opt_D_dump_absC "Abstract C" (dumpRealC abstractC)       >>
+    return flat_abstractC
+
+  where
+    data_tycons = filter isDataTyCon (tycons ++ map classTyCon classes)
+                       -- Generate info tables  for the data constrs arising
+                       -- from class decls as well
+
+    maybe_split = if opt_EnsureSplittableC 
+                 then CSplitMarker 
+                 else AbsCNop
+    cinfo       = MkCompInfo mod_name
+\end{code}
+
+Cost-centre profiling:
+Besides the usual stuff, we must produce:
+
+* Declarations for the cost-centres defined in this module;
+* Code to participate in "registering" all the cost-centres
+  in the program (done at startup time when the pgm is run).
+
+(The local cost-centres involved in this are passed
+into the code-generator, as are the imported-modules' names.)
+
+\begin{code}
+mkCostCentreStuff mod_name import_names (local_CCs, extern_CCs, singleton_CCSs)
+  | not opt_SccProfilingOn = AbsCNop
+  | otherwise = mkAbstractCs (
                    map (CCostCentreDecl True)   local_CCs ++
                    map (CCostCentreDecl False)  extern_CCs ++
                    map CCostCentreStackDecl     singleton_CCSs ++
                    mkCcRegister local_CCs singleton_CCSs import_names
                    map (CCostCentreDecl True)   local_CCs ++
                    map (CCostCentreDecl False)  extern_CCs ++
                    map CCostCentreStackDecl     singleton_CCSs ++
                    mkCcRegister local_CCs singleton_CCSs import_names
-                  )
-   in
-   mkAbstractCs [ cost_centre_stuff, module_code ]
+               )
 
   where
     mkCcRegister ccs cc_stacks import_names
 
   where
     mkCcRegister ccs cc_stacks import_names
@@ -117,7 +134,7 @@ codeGen mod_name (local_CCs, extern_CCs, singleton_CCSs)
 
        mk_import_register import_name
          = CCallProfCCMacro SLIT("REGISTER_IMPORT") 
 
        mk_import_register import_name
          = CCallProfCCMacro SLIT("REGISTER_IMPORT") 
-             [CLitLit (_PK_ ("_reg" ++ moduleString import_name)) AddrRep]
+             [CLitLit (_PK_ ("_reg" ++ moduleNameString import_name)) AddrRep]
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************