\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,
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,
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 )
import FamInstEnv ( FamInstEnv, FamInst )
import Rules ( RuleBase )
import CoreSyn ( CoreBind )
+import VarEnv
import VarSet
+import Var
import Id
import Type ( TyThing(..) )
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 )
import StringBuffer ( StringBuffer )
import System.Time ( ClockTime )
-import Data.IORef ( IORef, readIORef )
+import Data.IORef
import Data.Array ( Array, array )
\end{code}
-- 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.
\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)
-- 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}
%************************************************************************
-- 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
-- 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,
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
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:
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
ic_rn_gbl_env :: GlobalRdrEnv, -- The cached GlobalRdrEnv, built from
-- ic_toplev_scope and ic_exports
- ic_type_env :: TypeEnv, -- Type env for names bound during
- -- interaction. NB. the names from
- -- these Ids are used to populate
- -- the LocalRdrEnv used during
- -- typechecking of a statement, so
- -- there should be no duplicate
- -- names in here.
+ ic_tmp_ids :: [Id], -- Names bound during interaction.
+ -- Later Ids shadow
+ -- earlier ones with the same OccName.
ic_tyvars :: TyVarSet -- skolem type variables free in
- -- ic_type_env. These arise at
+ -- 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_type_env = emptyTypeEnv,
- ic_tyvars = emptyVarSet }
+ ic_tmp_ids = [],
+ ic_tyvars = emptyVarSet
+#ifdef GHCI
+ , ic_resume = []
+#endif
+ }
icPrintUnqual :: InteractiveContext -> PrintUnqualified
icPrintUnqual ictxt = mkPrintUnqualified (ic_rn_gbl_env ictxt)
-> TyVarSet
-> InteractiveContext
extendInteractiveContext ictxt ids tyvars
- = ictxt { ic_type_env = extendTypeEnvWithIds filtered_type_env ids,
+ = 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 }
- where
- type_env = ic_type_env ictxt
- bound_names = map idName ids
- -- Remove any shadowed bindings from the type_env;
- -- we aren't allowed any duplicates because the LocalRdrEnv is
- -- build directly from the Ids in the type env in here.
- old_bound_names = map idName (typeEnvIds type_env)
- shadowed = [ n | name <- bound_names,
- n <- old_bound_names,
- nameOccName name == nameOccName n ]
- filtered_type_env = delListFromNameEnv type_env shadowed
\end{code}
%************************************************************************
type PackageRuleBase = RuleBase
type PackageInstEnv = InstEnv
type PackageFamInstEnv = FamInstEnv
+type PackageVectInfo = VectInfo
data ExternalPackageState
= EPS {
-- 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
}
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
%************************************************************************
%* *
+\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}
+
+%************************************************************************
+%* *
\subsection{Linkable stuff}
%* *
%************************************************************************