diff options
Diffstat (limited to 'compiler/GHC/Unit/Module')
-rw-r--r-- | compiler/GHC/Unit/Module/Graph.hs | 8 | ||||
-rw-r--r-- | compiler/GHC/Unit/Module/ModIface.hs | 17 | ||||
-rw-r--r-- | compiler/GHC/Unit/Module/Status.hs | 4 | ||||
-rw-r--r-- | compiler/GHC/Unit/Module/WholeCoreBindings.hs | 63 |
4 files changed, 83 insertions, 9 deletions
diff --git a/compiler/GHC/Unit/Module/Graph.hs b/compiler/GHC/Unit/Module/Graph.hs index f8b0bcc2c3..fcd6a63a28 100644 --- a/compiler/GHC/Unit/Module/Graph.hs +++ b/compiler/GHC/Unit/Module/Graph.hs @@ -282,12 +282,12 @@ showModMsg dflags recomp (ModuleNode _ mod_summary) = mod_str = showPpr dflags mod ++ hscSourceString (ms_hsc_src mod_summary) dyn_file = op $ msDynObjFilePath mod_summary obj_file = op $ msObjFilePath mod_summary + files = [ obj_file ] + ++ [ dyn_file | gopt Opt_BuildDynamicToo dflags ] + ++ [ "interpreted" | gopt Opt_ByteCodeAndObjectCode dflags ] message = case backendSpecialModuleSource (backend dflags) recomp of Just special -> text special - Nothing -> - if gopt Opt_BuildDynamicToo dflags - then text obj_file <> comma <+> text dyn_file - else text obj_file + Nothing -> foldr1 (\ofile rest -> ofile <> comma <+> rest) (map text files) diff --git a/compiler/GHC/Unit/Module/ModIface.hs b/compiler/GHC/Unit/Module/ModIface.hs index 76cfff2b9f..1d5280f4fa 100644 --- a/compiler/GHC/Unit/Module/ModIface.hs +++ b/compiler/GHC/Unit/Module/ModIface.hs @@ -200,6 +200,11 @@ data ModIface_ (phase :: ModIfacePhase) -- Ditto data constructors, class operations, except that -- the hash of the parent class/tycon changes + mi_extra_decls :: Maybe [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo], + -- ^ Extra variable definitions which are **NOT** exposed but when + -- combined with mi_decls allows us to restart code generation. + -- See Note [Interface Files with Core Definitions] and Note [Interface File with Core: Sharing RHSs] + mi_globals :: !(Maybe GlobalRdrEnv), -- ^ Binds all the things defined at the top level in -- the /original source/ code for this module. which @@ -349,6 +354,7 @@ instance Binary ModIface where mi_warns = warns, mi_anns = anns, mi_decls = decls, + mi_extra_decls = extra_decls, mi_insts = insts, mi_fam_insts = fam_insts, mi_rules = rules, @@ -392,6 +398,7 @@ instance Binary ModIface where lazyPut bh warns lazyPut bh anns put_ bh decls + put_ bh extra_decls put_ bh insts put_ bh fam_insts lazyPut bh rules @@ -423,6 +430,7 @@ instance Binary ModIface where warns <- {-# SCC "bin_warns" #-} lazyGet bh anns <- {-# SCC "bin_anns" #-} lazyGet bh decls <- {-# SCC "bin_tycldecls" #-} get bh + extra_decls <- get bh insts <- {-# SCC "bin_insts" #-} get bh fam_insts <- {-# SCC "bin_fam_insts" #-} get bh rules <- {-# SCC "bin_rules" #-} lazyGet bh @@ -446,6 +454,7 @@ instance Binary ModIface where mi_fixities = fixities, mi_warns = warns, mi_decls = decls, + mi_extra_decls = extra_decls, mi_globals = Nothing, mi_insts = insts, mi_fam_insts = fam_insts, @@ -494,6 +503,7 @@ emptyPartialModIface mod mi_fam_insts = [], mi_rules = [], mi_decls = [], + mi_extra_decls = Nothing, mi_globals = Nothing, mi_hpc = False, mi_trust = noIfaceTrustInfo, @@ -541,12 +551,13 @@ emptyIfaceHashCache _occ = Nothing -- avoid major space leaks. instance (NFData (IfaceBackendExts (phase :: ModIfacePhase)), NFData (IfaceDeclExts (phase :: ModIfacePhase))) => NFData (ModIface_ phase) where rnf (ModIface f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 - f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23) = + f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23 f24) = rnf f1 `seq` rnf f2 `seq` f3 `seq` f4 `seq` f5 `seq` f6 `seq` rnf f7 `seq` f8 `seq` - f9 `seq` rnf f10 `seq` rnf f11 `seq` f12 `seq` rnf f13 `seq` rnf f14 `seq` rnf f15 `seq` - rnf f16 `seq` f17 `seq` rnf f18 `seq` rnf f19 `seq` f20 `seq` f21 `seq` f22 `seq` rnf f23 + f9 `seq` rnf f10 `seq` rnf f11 `seq` rnf f12 `seq` f13 `seq` rnf f14 `seq` rnf f15 `seq` rnf f16 `seq` + rnf f17 `seq` f18 `seq` rnf f19 `seq` rnf f20 `seq` f21 `seq` f22 `seq` f23 `seq` rnf f24 `seq` () + instance NFData (ModIfaceBackend) where rnf (ModIfaceBackend f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13) = rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4 `seq` diff --git a/compiler/GHC/Unit/Module/Status.hs b/compiler/GHC/Unit/Module/Status.hs index 6f926e3fb2..49851b74eb 100644 --- a/compiler/GHC/Unit/Module/Status.hs +++ b/compiler/GHC/Unit/Module/Status.hs @@ -10,13 +10,13 @@ import GHC.Unit.Module.ModGuts import GHC.Unit.Module.ModIface import GHC.Utils.Fingerprint -import GHC.Linker.Types import GHC.Utils.Outputable +import GHC.Unit.Home.ModInfo -- | Status of a module in incremental compilation data HscRecompStatus -- | Nothing to do because code already exists. - = HscUpToDate ModIface (Maybe Linkable) + = HscUpToDate ModIface HomeModLinkable -- | Recompilation of module, or update of interface is required. Optionally -- pass the old interface hash to avoid updating the existing interface when -- it has not changed. diff --git a/compiler/GHC/Unit/Module/WholeCoreBindings.hs b/compiler/GHC/Unit/Module/WholeCoreBindings.hs new file mode 100644 index 0000000000..8e84abbf57 --- /dev/null +++ b/compiler/GHC/Unit/Module/WholeCoreBindings.hs @@ -0,0 +1,63 @@ +module GHC.Unit.Module.WholeCoreBindings where + +import GHC.Unit.Types (Module) +import GHC.Unit.Module.Location +import GHC.Iface.Syntax + +{- +Note [Interface Files with Core Definitions] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A interface file can optionally contain the definitions of all core bindings, this +is enabled by the flag `-fwrite-if-simplified-core`. +This provides everything needed in addition to the normal ModIface and ModDetails +to restart compilation after typechecking to generate bytecode. The `fi_bindings` field +is stored in the normal interface file and the other fields populated whilst loading +the interface file. + +The lifecycle of a WholeCoreBindings typically proceeds as follows: + +1. The ModIface which contains mi_extra_decls is loaded from disk. A linkable is + created (which is headed by the `CoreBindings` constructor). This is an unhydrated set of bindings which + is currently unsuitable for linking, but at the point it is loaded, the ModIface + hasn't been hydrated yet (See Note [Hydrating Modules]) either so the CoreBindings constructor allows the delaying of converting + the WholeCoreBindings into a proper Linkable (if we ever do that). The CoreBindings constructor also + allows us to convert the WholeCoreBindings into multiple different linkables if we so desired. + +2. `initWholeCoreBindings` turns a WholeCoreBindings into a proper BCO linkable. This step combines together + all the necessary information from a ModIface, ModDetails and WholeCoreBindings in order to + create the linkable. The linkable created is a "LoadedBCOs" linkable, which + was introduced just for initWholeCoreBindings, so that the bytecode can be generated lazilly. + Using the `BCOs` constructor directly here leads to the bytecode being forced + too eagerly. + +3. Then when bytecode is needed, the LoadedBCOs value is inspected and unpacked and + the linkable is used as before. + +The flag `-fwrite-if-simplfied-core` determines whether the extra information is written +to an interface file. The program which is written is the core bindings of the module +after whatever simplification the user requested has been performed. So the simplified core bindings +of the interface file agree with the optimisation level as reported by the interface +file. + +Note [Size of Interface Files with Core Definitions] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +How much overhead does `-fwrite-if-simplfied-core` add to a typical interface file? +As an experiment I compiled the `Cabal` library and `ghc` library (Aug 22) with + +| Project | .hi | .hi (fat) | .o | +| --------| ---- | --------- | -- | +| ghc | 32M | 68M | 127M | +| Cabal | 3.2M | 9.8M | 14M | + +So the interface files gained in size but the end result was still smaller than +the object files. + +-} + +data WholeCoreBindings = WholeCoreBindings + { wcb_bindings :: [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] + , wcb_module :: Module + , wcb_mod_location :: ModLocation + } |