Add data type information to VectInfo
[ghc-hetmet.git] / compiler / main / HscTypes.lhs
index 1101e86..fb8e87e 100644 (file)
@@ -6,7 +6,8 @@
 \begin{code}
 module HscTypes ( 
        -- * Sessions and compilation state
-       Session(..), HscEnv(..), hscEPS,
+       Session(..), withSession, modifySession, 
+        HscEnv(..), hscEPS,
        FinderCache, FindResult(..), ModLocationCache,
        Target(..), TargetId(..), pprTarget, pprTargetId,
        ModuleGraph, emptyMG,
@@ -14,20 +15,20 @@ module HscTypes (
        ModDetails(..), emptyModDetails,
        ModGuts(..), CgGuts(..), ModImports(..), ForeignStubs(..),
 
-       ModSummary(..), showModMsg, isBootSummary,
+       ModSummary(..), ms_mod_name, showModMsg, isBootSummary,
        msHsFilePath, msHiFilePath, msObjFilePath, 
 
        HscSource(..), isHsBoot, hscSourceString,       -- Re-exported from DriverPhases
        
        HomePackageTable, HomeModInfo(..), emptyHomePackageTable,
-       hptInstances, hptRules,
+       hptInstances, hptRules, hptVectInfo,
 
        ExternalPackageState(..), EpsStats(..), addEpsInStats,
        PackageTypeEnv, PackageIfaceTable, emptyPackageIfaceTable,
        lookupIfaceByModule, emptyModIface,
 
        InteractiveContext(..), emptyInteractiveContext, 
-       icPrintUnqual, mkPrintUnqualified,
+       icPrintUnqual, mkPrintUnqualified, extendInteractiveContext,
 
        ModIface(..), mkIfaceDepCache, mkIfaceVerCache, mkIfaceFixCache,
        emptyIfaceDepCache,
@@ -59,20 +60,24 @@ module HscTypes (
        Linkable(..), isObjectLinkable,
        Unlinked(..), CompiledByteCode,
        isObject, nameOfObject, isInterpretable, byteCodeOfObject,
-        HpcInfo, noHpcInfo,
+        HpcInfo(..), noHpcInfo,
 
         -- Breakpoints
-        ModBreaks (..), BreakIndex, emptyModBreaks
+        ModBreaks (..), BreakIndex, emptyModBreaks,
+
+        -- Vectorisation information
+        VectInfo(..), IfaceVectInfo(..), noVectInfo, plusVectInfo, 
+        noIfaceVectInfo
     ) where
 
 #include "HsVersions.h"
 
 #ifdef GHCI
 import ByteCodeAsm     ( CompiledByteCode )
+import {-# SOURCE #-}  InteractiveEval ( Resume )
 #endif
 
-import RdrName         ( GlobalRdrEnv, emptyGlobalRdrEnv,
-                         LocalRdrEnv, emptyLocalRdrEnv, GlobalRdrElt(..), 
+import RdrName         ( GlobalRdrEnv, emptyGlobalRdrEnv, GlobalRdrElt(..), 
                           unQualOK, ImpDeclSpec(..), Provenance(..),
                           ImportSpec(..), lookupGlobalRdrEnv )
 import Name            ( Name, NamedThing, getName, nameOccName, nameModule )
@@ -85,7 +90,10 @@ import InstEnv               ( InstEnv, Instance )
 import FamInstEnv      ( FamInstEnv, FamInst )
 import Rules           ( RuleBase )
 import CoreSyn         ( CoreBind )
-import Id              ( Id, isImplicitId )
+import VarEnv
+import VarSet
+import Var
+import Id
 import Type            ( TyThing(..) )
 
 import Class           ( Class, classSelIds, classATs, classTyCon )
@@ -93,7 +101,7 @@ import TyCon
 import DataCon         ( DataCon, dataConImplicitIds )
 import PrelNames       ( gHC_PRIM )
 import Packages                ( PackageId )
-import DynFlags                ( DynFlags(..), DynFlag(..), isOneShot, HscTarget (..) )
+import DynFlags                ( DynFlags(..), isOneShot, HscTarget (..) )
 import DriverPhases    ( HscSource(..), isHsBoot, hscSourceString, Phase )
 import BasicTypes      ( Version, initialVersion, IPName, 
                          Fixity, defaultFixity, DeprecTxt )
@@ -111,7 +119,7 @@ import FastString   ( FastString )
 import StringBuffer    ( StringBuffer )
 
 import System.Time     ( ClockTime )
-import Data.IORef      ( IORef, readIORef )
+import Data.IORef
 import Data.Array       ( Array, array )
 \end{code}
 
@@ -129,6 +137,12 @@ import Data.Array       ( Array, array )
 -- constituting the current program or library, the context for
 -- interactive evaluation, and various caches.
 newtype Session = Session (IORef HscEnv)
+
+withSession :: Session -> (HscEnv -> IO a) -> IO a
+withSession (Session ref) f = do h <- readIORef ref; f h
+
+modifySession :: Session -> (HscEnv -> HscEnv) -> IO ()
+modifySession (Session ref) f = do h <- readIORef ref; writeIORef ref $! f h
 \end{code}
 
 HscEnv is like Session, except that some of the fields are immutable.
@@ -274,16 +288,19 @@ lookupIfaceByModule dflags hpt pit mod
 
 
 \begin{code}
-hptInstances :: HscEnv -> (ModuleName -> Bool) -> [Instance]
--- Find all the instance declarations that are in modules imported 
--- by this one, directly or indirectly, and are in the Home Package Table
--- This ensures that we don't see instances from modules --make compiled 
--- before this one, but which are not below this one
+hptInstances :: HscEnv -> (ModuleName -> Bool) -> ([Instance], [FamInst])
+-- Find all the instance declarations (of classes and families) that are in
+-- modules imported by this one, directly or indirectly, and are in the Home
+-- Package Table.  This ensures that we don't see instances from modules --make
+-- compiled before this one, but which are not below this one.
 hptInstances hsc_env want_this_module
-  = [ ispec 
-    | mod_info <- eltsUFM (hsc_HPT hsc_env)
-    , want_this_module (moduleName (mi_module (hm_iface mod_info)))
-    , ispec <- md_insts (hm_details mod_info) ]
+  = let (insts, famInsts) = unzip
+          [ (md_insts details, md_fam_insts details)
+          | mod_info <- eltsUFM (hsc_HPT hsc_env)
+          , want_this_module (moduleName (mi_module (hm_iface mod_info)))
+          , let details = hm_details mod_info ]
+    in
+    (concat insts, concat famInsts)
 
 hptRules :: HscEnv -> [(ModuleName, IsBootInterface)] -> [CoreRule]
 -- Get rules from modules "below" this one (in the dependency sense)
@@ -315,6 +332,15 @@ hptRules hsc_env deps
 
        -- And get its dfuns
     , rule <- rules ]
+
+hptVectInfo :: HscEnv -> VectInfo
+-- Get the combined VectInfo of all modules in the home package table.  In
+-- contrast to instances and rules, we don't care whether the modules are
+-- "below" or us.  The VectInfo of those modules not "below" us does not
+-- affect the compilation of the current module.
+hptVectInfo hsc_env 
+  = foldr plusVectInfo noVectInfo [ md_vect_info (hm_details mod_info)
+                                  | mod_info <- eltsUFM (hsc_HPT hsc_env)]
 \end{code}
 
 %************************************************************************
@@ -438,6 +464,9 @@ data ModIface
                                        -- instances (for classes and families)
                                        -- combined
 
+                -- Vectorisation information
+        mi_vect_info :: !IfaceVectInfo,
+
                -- Cached environments for easy lookup
                -- These are computed (lazily) from other fields
                -- and are not put into the interface file
@@ -457,10 +486,11 @@ data ModDetails
        -- The next two fields are created by the typechecker
        md_exports   :: [AvailInfo],
         md_types     :: !TypeEnv,
-        md_insts     :: ![Instance],   -- Dfun-ids for the instances in this module
+        md_insts     :: ![Instance],  -- Dfun-ids for the instances in this module
         md_fam_insts :: ![FamInst],
-        md_rules     :: ![CoreRule],   -- Domain may include Ids from other modules
-        md_modBreaks :: !ModBreaks  -- breakpoint information for this module 
+        md_rules     :: ![CoreRule],  -- Domain may include Ids from other modules
+        md_modBreaks :: !ModBreaks,   -- Breakpoint information for this module 
+        md_vect_info :: !VectInfo     -- Vectorisation information
      }
 
 emptyModDetails = ModDetails { md_types = emptyTypeEnv,
@@ -468,7 +498,9 @@ emptyModDetails = ModDetails { md_types = emptyTypeEnv,
                               md_insts     = [],
                               md_rules     = [],
                               md_fam_insts = [],
-                               md_modBreaks = emptyModBreaks } 
+                               md_modBreaks = emptyModBreaks,
+                               md_vect_info = noVectInfo
+                             } 
 
 -- A ModGuts is carried through the compiler, accumulating stuff as it goes
 -- There is only one ModGuts at any time, the one for the module
@@ -502,7 +534,8 @@ data ModGuts
        mg_foreign   :: !ForeignStubs,
        mg_deprecs   :: !Deprecations,   -- Deprecations declared in the module
        mg_hpc_info  :: !HpcInfo,        -- info about coverage tick boxes
-        mg_modBreaks :: !ModBreaks
+        mg_modBreaks :: !ModBreaks,
+        mg_vect_info :: !VectInfo        -- Pool of vectorised declarations
     }
 
 -- The ModGuts takes on several slightly different forms:
@@ -589,6 +622,7 @@ emptyModIface mod
               mi_decls     = [],
               mi_globals   = Nothing,
               mi_rule_vers = initialVersion,
+               mi_vect_info = noIfaceVectInfo,
               mi_dep_fn = emptyIfaceDepCache,
               mi_fix_fn = emptyIfaceFixCache,
               mi_ver_fn = emptyIfaceVerCache
@@ -614,21 +648,47 @@ data InteractiveContext
        ic_rn_gbl_env :: GlobalRdrEnv,  -- The cached GlobalRdrEnv, built from
                                        -- ic_toplev_scope and ic_exports
 
-       ic_rn_local_env :: LocalRdrEnv, -- Lexical context for variables bound
-                                       -- during interaction
+       ic_tmp_ids :: [Id],             -- Names bound during interaction.
+                                        -- Later Ids shadow
+                                        -- earlier ones with the same OccName.
 
-       ic_type_env :: TypeEnv          -- Ditto for types
+        ic_tyvars :: TyVarSet           -- skolem type variables free in
+                                        -- ic_tmp_ids.  These arise at
+                                        -- breakpoints in a polymorphic 
+                                        -- context, where we have only partial
+                                        -- type information.
+
+#ifdef GHCI
+        , ic_resume :: [Resume]         -- the stack of breakpoint contexts
+#endif
     }
 
+
 emptyInteractiveContext
   = InteractiveContext { ic_toplev_scope = [],
                         ic_exports = [],
                         ic_rn_gbl_env = emptyGlobalRdrEnv,
-                        ic_rn_local_env = emptyLocalRdrEnv,
-                        ic_type_env = emptyTypeEnv }
+                        ic_tmp_ids = [],
+                         ic_tyvars = emptyVarSet
+#ifdef GHCI
+                         , ic_resume = []
+#endif
+                       }
 
 icPrintUnqual :: InteractiveContext -> PrintUnqualified
 icPrintUnqual ictxt = mkPrintUnqualified (ic_rn_gbl_env ictxt)
+
+
+extendInteractiveContext
+        :: InteractiveContext
+        -> [Id]
+        -> TyVarSet
+        -> InteractiveContext
+extendInteractiveContext ictxt ids tyvars
+  = ictxt { ic_tmp_ids =  ic_tmp_ids ictxt ++ ids,
+                          -- NB. must be this way around, because we want
+                          -- new ids to shadow existing bindings.
+            ic_tyvars   = ic_tyvars ictxt `unionVarSet` tyvars }
 \end{code}
 
 %************************************************************************
@@ -989,6 +1049,7 @@ type PackageTypeEnv    = TypeEnv
 type PackageRuleBase   = RuleBase
 type PackageInstEnv    = InstEnv
 type PackageFamInstEnv = FamInstEnv
+type PackageVectInfo   = VectInfo
 
 data ExternalPackageState
   = EPS {
@@ -1025,10 +1086,10 @@ data ExternalPackageState
                                               -- modules 
        eps_fam_inst_env :: !PackageFamInstEnv,-- Ditto FamInstEnv
        eps_rule_base    :: !PackageRuleBase,  -- Ditto RuleEnv
+        eps_vect_info    :: !PackageVectInfo,  -- Ditto VectInfo
 
         eps_mod_fam_inst_env :: !(ModuleEnv FamInstEnv), -- identifies family
-                                                      -- instances of each mod
-
+                                                      -- instances of each mod 
        eps_stats :: !EpsStats
   }
 
@@ -1110,6 +1171,9 @@ data ModSummary
        ms_hspp_buf  :: Maybe StringBuffer      -- The actual preprocessed source, maybe.
      }
 
+ms_mod_name :: ModSummary -> ModuleName
+ms_mod_name = moduleName . ms_mod
+
 -- The ModLocation contains both the original source filename and the
 -- filename of the cleaned-up source file after all preprocessing has been
 -- done.  The point is that the summariser will have to cpp/unlit/whatever
@@ -1162,10 +1226,71 @@ showModMsg target recomp mod_summary
 %************************************************************************
 
 \begin{code}
-type HpcInfo = Int             -- just the number of ticks in a module
+data HpcInfo = HpcInfo 
+     { hpcInfoTickCount :: Int 
+     , hpcInfoHash      :: Int  
+     }
+     | NoHpcInfo
 
 noHpcInfo :: HpcInfo
-noHpcInfo = 0                  -- default = 0
+noHpcInfo = NoHpcInfo
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{Vectorisation Support}
+%*                                                                     *
+%************************************************************************
+
+The following information is generated and consumed by the vectorisation
+subsystem.  It communicates the vectorisation status of declarations from one
+module to another.
+
+Why do we need both f and f_CC in the ModGuts/ModDetails/EPS version VectInfo
+below?  We need to know `f' when converting to IfaceVectInfo.  However, during
+closure conversion, we need to know `f_CC', whose `Var' we cannot lookup based
+on just the OccName easily in a Core pass.
+
+\begin{code}
+-- ModGuts/ModDetails/EPS version
+data VectInfo      
+  = VectInfo {
+      vectInfoCCVar     :: VarEnv  (Var    , Var  ),   -- (f, f_CC) keyed on f
+      vectInfoCCTyCon   :: NameEnv (TyCon  , TyCon),   -- (T, T_CC) keyed on T
+      vectInfoCCDataCon :: NameEnv (DataCon, DataCon), -- (C, C_CC) keyed on C
+      vectInfoCCIso     :: NameEnv (TyCon  , Var)      -- (T, isoT) keyed on T
+    }
+    -- all of this is always tidy, even in ModGuts
+
+-- ModIface version
+data IfaceVectInfo 
+  = IfaceVectInfo {
+      ifaceVectInfoCCVar        :: [Name],
+        -- all variables in here have a closure-converted variant;
+        -- the name of the CC'ed variant is determined by `mkCloOcc'
+      ifaceVectInfoCCTyCon      :: [Name],
+        -- all tycons in here have a closure-converted variant;
+        -- the name of the CC'ed variant and those of its data constructors are
+        -- determined by `mkCloTyConOcc' and `mkCloDataConOcc'; the names of
+        -- the isomorphisms is determined by `mkCloIsoOcc'
+      ifaceVectInfoCCTyConReuse :: [Name]              
+        -- the closure-converted form of all the tycons in here coincids with
+        -- the unconverted from; the names of the isomorphisms is determined
+        -- by `mkCloIsoOcc'
+    }
+
+noVectInfo :: VectInfo
+noVectInfo = VectInfo emptyVarEnv emptyNameEnv emptyNameEnv emptyNameEnv
+
+plusVectInfo :: VectInfo -> VectInfo -> VectInfo
+plusVectInfo vi1 vi2 = 
+  VectInfo (vectInfoCCVar     vi1 `plusVarEnv`  vectInfoCCVar     vi2)
+           (vectInfoCCTyCon   vi1 `plusNameEnv` vectInfoCCTyCon   vi2)
+           (vectInfoCCDataCon vi1 `plusNameEnv` vectInfoCCDataCon vi2)
+           (vectInfoCCIso     vi1 `plusNameEnv` vectInfoCCIso     vi2)
+
+noIfaceVectInfo :: IfaceVectInfo
+noIfaceVectInfo = IfaceVectInfo [] [] []
 \end{code}
 
 %************************************************************************
@@ -1253,6 +1378,8 @@ data ModBreaks
         -- indicating which breakpoints are enabled.
    , modBreaks_locs :: !(Array BreakIndex SrcSpan)
         -- An array giving the source span of each breakpoint.
+   , modBreaks_vars :: !(Array BreakIndex [OccName])
+        -- An array giving the names of the free variables at each breakpoint.
    }
 
 emptyModBreaks :: ModBreaks
@@ -1260,5 +1387,6 @@ emptyModBreaks = ModBreaks
    { modBreaks_flags = error "ModBreaks.modBreaks_array not initialised"
          -- Todo: can we avoid this? 
    , modBreaks_locs = array (0,-1) []
+   , modBreaks_vars = array (0,-1) []
    }
 \end{code}