Hannes Siebenhandl pushed to branch wip/fendor/linkable-usage at Glasgow Haskell Compiler / GHC

Commits:

25 changed files:

Changes:

  • compiler/GHC/ByteCode/Binary.hs
    ... ... @@ -20,7 +20,6 @@ import GHC.Prelude
    20 20
     
    
    21 21
     import GHC.ByteCode.Types
    
    22 22
     import GHC.Data.FastString
    
    23
    -import GHC.Driver.Env.Types (HscEnv(..))
    
    24 23
     import GHC.Types.Name
    
    25 24
     import GHC.Types.Name.Cache
    
    26 25
     import GHC.Types.Name.Env
    
    ... ... @@ -30,6 +29,7 @@ import GHC.Utils.Binary
    30 29
     import GHC.Utils.Exception
    
    31 30
     import GHC.Utils.Panic
    
    32 31
     import GHC.Utils.Outputable
    
    32
    +import GHC.Utils.Fingerprint (Fingerprint)
    
    33 33
     
    
    34 34
     import Control.Monad
    
    35 35
     import Data.Binary qualified as Binary
    
    ... ... @@ -47,6 +47,7 @@ import System.IO.Unsafe (unsafeInterleaveIO)
    47 47
     -- contained by 'ModuleByteCode' are stored in-memory rather than as file paths to
    
    48 48
     -- temporary files.
    
    49 49
     data OnDiskModuleByteCode = OnDiskModuleByteCode { odgbc_module :: Module
    
    50
    +                                                 , odgbc_hash :: Fingerprint
    
    50 51
                                                      , odgbc_compiled_byte_code :: CompiledByteCode
    
    51 52
                                                      , odgbc_foreign :: [ByteString]  -- ^ Contents of object files
    
    52 53
                                                      }
    
    ... ... @@ -94,6 +95,20 @@ instance Binary InterpreterLibraryContents where
    94 95
         putByte bh 1
    
    95 96
         put_ bh contents
    
    96 97
     
    
    98
    +instance Binary OnDiskModuleByteCode where
    
    99
    +  get bh = do
    
    100
    +    odgbc_hash <- get bh
    
    101
    +    odgbc_module <- get bh
    
    102
    +    odgbc_compiled_byte_code <- lazyGet bh
    
    103
    +    odgbc_foreign <- lazyGet bh
    
    104
    +    pure OnDiskModuleByteCode {..}
    
    105
    +
    
    106
    +  put_ bh OnDiskModuleByteCode {..} = do
    
    107
    +    put_ bh odgbc_hash
    
    108
    +    put_ bh odgbc_module
    
    109
    +    lazyPut bh odgbc_compiled_byte_code
    
    110
    +    lazyPut bh odgbc_foreign
    
    111
    +
    
    97 112
     instance Binary OnDiskBytecodeLib where
    
    98 113
       get bh = do
    
    99 114
         bytecodeLibUnitId <- get bh
    
    ... ... @@ -106,18 +121,6 @@ instance Binary OnDiskBytecodeLib where
    106 121
         put_ bh bytecodeLibFiles
    
    107 122
         put_ bh bytecodeLibForeign
    
    108 123
     
    
    109
    -instance Binary OnDiskModuleByteCode where
    
    110
    -  get bh = do
    
    111
    -    odgbc_module <- get bh
    
    112
    -    odgbc_compiled_byte_code <- get bh
    
    113
    -    odgbc_foreign <- get bh
    
    114
    -    pure OnDiskModuleByteCode {..}
    
    115
    -
    
    116
    -  put_ bh OnDiskModuleByteCode {..} = do
    
    117
    -    put_ bh odgbc_module
    
    118
    -    put_ bh odgbc_compiled_byte_code
    
    119
    -    put_ bh odgbc_foreign
    
    120
    -
    
    121 124
     instance Binary CompiledByteCode where
    
    122 125
       get bh = do
    
    123 126
         bc_bcos <- get bh
    
    ... ... @@ -252,8 +255,8 @@ addBinNameWriter bh' = do
    252 255
               Just idx -> (b, idx)
    
    253 256
               Nothing  -> (ByteCodeNameEnv (next + 1) (extendNameEnv subst name next), next))
    
    254 257
     
    
    255
    -addBinNameReader :: HscEnv -> ReadBinHandle -> IO ReadBinHandle
    
    256
    -addBinNameReader HscEnv {hsc_NC} bh' = do
    
    258
    +addBinNameReader :: NameCache -> ReadBinHandle -> IO ReadBinHandle
    
    259
    +addBinNameReader nc bh' = do
    
    257 260
       env_ref <- newIORef emptyOccEnv
    
    258 261
       pure $ flip addReaderToUserData bh' $ BinaryReader $ \bh -> do
    
    259 262
         t <- getByte bh
    
    ... ... @@ -266,7 +269,7 @@ addBinNameReader HscEnv {hsc_NC} bh' = do
    266 269
             -- We don't want to get a new unique from the NameCache each time we
    
    267 270
             -- see a name.
    
    268 271
             nm' <- unsafeInterleaveIO $ do
    
    269
    -          u <- takeUniqFromNameCache hsc_NC
    
    272
    +          u <- takeUniqFromNameCache nc
    
    270 273
               evaluate $ mkInternalName u occ noSrcSpan
    
    271 274
             fmap BinName $ atomicModifyIORef' env_ref $ \env ->
    
    272 275
               case lookupOccEnv env occ of
    

  • compiler/GHC/ByteCode/Recomp/Binary.hs
    1
    +module GHC.ByteCode.Recomp.Binary (
    
    2
    +  -- * Fingerprinting ByteCode objects
    
    3
    +  computeFingerprint,
    
    4
    +) where
    
    5
    +
    
    6
    +import GHC.Prelude
    
    7
    +
    
    8
    +import GHC.ByteCode.Binary (addBinNameWriter)
    
    9
    +import GHC.Iface.Binary
    
    10
    +import GHC.Iface.Recomp.Binary (putNameLiterally, fingerprintBinMem)
    
    11
    +import GHC.Types.Name
    
    12
    +import GHC.Utils.Fingerprint
    
    13
    +import GHC.Utils.Binary
    
    14
    +
    
    15
    +import System.IO.Unsafe
    
    16
    +
    
    17
    +-- | Create a 'Fingerprint' using the appropriate serializers
    
    18
    +-- for 'ModuleByteCode'.
    
    19
    +--
    
    20
    +computeFingerprint :: (Binary a)
    
    21
    +                   => (WriteBinHandle -> Name -> IO ())
    
    22
    +                   -> a
    
    23
    +                   -> Fingerprint
    
    24
    +computeFingerprint put_nonbinding_name a = unsafePerformIO $ do
    
    25
    +    bh <- fmap set_user_data $ openBinMem (3*1024) -- just less than a block
    
    26
    +    bh' <- addBinNameWriter bh
    
    27
    +    putWithUserData QuietBinIFace NormalCompression bh' a
    
    28
    +    fingerprintBinMem bh'
    
    29
    +  where
    
    30
    +    set_user_data bh = setWriterUserData bh $ mkWriterUserData
    
    31
    +      [ mkSomeBinaryWriter $ mkWriter put_nonbinding_name
    
    32
    +      , mkSomeBinaryWriter $ simpleBindingNameWriter $ mkWriter putNameLiterally
    
    33
    +      , mkSomeBinaryWriter $ mkWriter putFS
    
    34
    +      ]

  • compiler/GHC/ByteCode/Serialize.hs
    ... ... @@ -2,11 +2,11 @@
    2 2
     {-# LANGUAGE RecordWildCards #-}
    
    3 3
     -- Orphans are here since the Binary instances use an ad-hoc means of serialising
    
    4 4
     -- names which we don't want to pollute the rest of the codebase with.
    
    5
    -{-# OPTIONS_GHC -Wno-orphans #-}
    
    6 5
     {- | This module implements the serialization of bytecode objects to and from disk.
    
    7 6
     -}
    
    8 7
     module GHC.ByteCode.Serialize
    
    9
    -  ( writeBinByteCode, readBinByteCode, ModuleByteCode(..)
    
    8
    +  ( writeBinByteCode, readBinByteCode
    
    9
    +  , ModuleByteCode(..)
    
    10 10
       , BytecodeLibX(..)
    
    11 11
       , BytecodeLib
    
    12 12
       , OnDiskBytecodeLib
    
    ... ... @@ -14,26 +14,34 @@ module GHC.ByteCode.Serialize
    14 14
       , InterpreterLibraryContents(..)
    
    15 15
       , writeBytecodeLib
    
    16 16
       , readBytecodeLib
    
    17
    +  , mkModuleByteCode
    
    18
    +  , fingerprintModuleByteCodeContents
    
    17 19
       , decodeOnDiskModuleByteCode
    
    18 20
       , decodeOnDiskBytecodeLib
    
    19 21
       )
    
    20 22
     where
    
    21 23
     
    
    22
    -import Control.Monad
    
    24
    +import GHC.Prelude
    
    25
    +
    
    26
    +import GHC.ByteCode.Binary
    
    27
    +import GHC.ByteCode.Types
    
    28
    +import GHC.ByteCode.Recomp.Binary (computeFingerprint)
    
    23 29
     import GHC.Driver.Env
    
    30
    +import GHC.Driver.DynFlags
    
    24 31
     import GHC.Iface.Binary
    
    25
    -import GHC.Prelude
    
    32
    +import GHC.Iface.Recomp.Binary (putNameLiterally)
    
    33
    +import GHC.Linker.Types
    
    34
    +import GHC.Unit.Types
    
    26 35
     import GHC.Utils.Binary
    
    27 36
     import GHC.Utils.TmpFs
    
    28
    -import System.FilePath
    
    29
    -import GHC.Driver.DynFlags
    
    30
    -import System.Directory
    
    37
    +import GHC.Utils.Logger
    
    38
    +import GHC.Utils.Fingerprint (Fingerprint)
    
    39
    +
    
    31 40
     import Data.ByteString (ByteString)
    
    32 41
     import qualified Data.ByteString as BS
    
    33 42
     import Data.Traversable
    
    34
    -import GHC.Utils.Logger
    
    35
    -import GHC.Linker.Types
    
    36
    -import GHC.ByteCode.Binary
    
    43
    +import System.Directory
    
    44
    +import System.FilePath
    
    37 45
     
    
    38 46
     {- Note [Overview of persistent bytecode]
    
    39 47
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -85,7 +93,7 @@ writeBytecodeLib lib path = do
    85 93
     readBytecodeLib :: HscEnv -> FilePath -> IO OnDiskBytecodeLib
    
    86 94
     readBytecodeLib hsc_env path = do
    
    87 95
       bh' <- readBinMem path
    
    88
    -  bh <- addBinNameReader hsc_env bh'
    
    96
    +  bh <- addBinNameReader (hsc_NC hsc_env) bh'
    
    89 97
       res <- getWithUserData (hsc_NC hsc_env) bh
    
    90 98
       pure res
    
    91 99
     
    
    ... ... @@ -103,7 +111,8 @@ decodeOnDiskModuleByteCode hsc_env odbco = do
    103 111
       pure $ ModuleByteCode {
    
    104 112
         gbc_module = odgbc_module odbco,
    
    105 113
         gbc_compiled_byte_code = odgbc_compiled_byte_code odbco,
    
    106
    -    gbc_foreign_files = foreign_files
    
    114
    +    gbc_foreign_files = foreign_files,
    
    115
    +    gbc_hash = odgbc_hash odbco
    
    107 116
        }
    
    108 117
     
    
    109 118
     decodeOnDiskBytecodeLib :: HscEnv -> OnDiskBytecodeLib -> IO BytecodeLib
    
    ... ... @@ -162,7 +171,8 @@ encodeOnDiskModuleByteCode bco = do
    162 171
       pure $ OnDiskModuleByteCode {
    
    163 172
         odgbc_module = gbc_module bco,
    
    164 173
         odgbc_compiled_byte_code = gbc_compiled_byte_code bco,
    
    165
    -    odgbc_foreign = foreign_contents
    
    174
    +    odgbc_foreign = foreign_contents,
    
    175
    +    odgbc_hash = gbc_hash bco
    
    166 176
        }
    
    167 177
     
    
    168 178
     -- | Read a 'ModuleByteCode' from a file.
    
    ... ... @@ -174,7 +184,7 @@ readBinByteCode hsc_env f = do
    174 184
     readOnDiskModuleByteCode :: HscEnv -> FilePath -> IO OnDiskModuleByteCode
    
    175 185
     readOnDiskModuleByteCode hsc_env f = do
    
    176 186
       bh' <- readBinMem f
    
    177
    -  bh <- addBinNameReader hsc_env bh'
    
    187
    +  bh <- addBinNameReader (hsc_NC hsc_env) bh'
    
    178 188
       getWithUserData (hsc_NC hsc_env) bh
    
    179 189
     
    
    180 190
     -- | Write a 'ModuleByteCode' to a file.
    
    ... ... @@ -186,3 +196,13 @@ writeBinByteCode f cbc = do
    186 196
       odbco <- encodeOnDiskModuleByteCode cbc
    
    187 197
       putWithUserData QuietBinIFace NormalCompression bh odbco
    
    188 198
       writeBinMem bh f
    
    199
    +
    
    200
    +mkModuleByteCode :: Module -> CompiledByteCode -> [FilePath] -> IO ModuleByteCode
    
    201
    +mkModuleByteCode modl cbc foreign_files = do
    
    202
    +  !bcos_hash <- fingerprintModuleByteCodeContents modl cbc foreign_files
    
    203
    +  return $! ModuleByteCode modl cbc foreign_files bcos_hash
    
    204
    +
    
    205
    +fingerprintModuleByteCodeContents :: Module -> CompiledByteCode -> [FilePath] -> IO Fingerprint
    
    206
    +fingerprintModuleByteCodeContents modl cbc foreign_files = do
    
    207
    +  foreign_contents <- readObjectFiles foreign_files
    
    208
    +  pure $ computeFingerprint putNameLiterally (modl, cbc, foreign_contents)

  • compiler/GHC/Driver/Hooks.hs
    ... ... @@ -137,7 +137,7 @@ data Hooks = Hooks
    137 137
       , tcForeignExportsHook   :: !(Maybe ([LForeignDecl GhcRn]
    
    138 138
                 -> TcM (LHsBinds GhcTc, [LForeignDecl GhcTc], Bag GlobalRdrElt)))
    
    139 139
       , hscFrontendHook        :: !(Maybe (ModSummary -> Hsc FrontendResult))
    
    140
    -  , hscCompileCoreExprHook :: !(Maybe (HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [Linkable], PkgsLoaded)))
    
    140
    +  , hscCompileCoreExprHook :: !(Maybe (HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [LinkableUsage], PkgsLoaded)))
    
    141 141
       , ghcPrimIfaceHook       :: !(Maybe ModIface)
    
    142 142
       , runPhaseHook           :: !(Maybe PhaseHook)
    
    143 143
       , runMetaHook            :: !(Maybe (MetaHook TcM))
    
    ... ... @@ -145,7 +145,7 @@ data Hooks = Hooks
    145 145
                                              -> HomePackageTable -> IO SuccessFlag))
    
    146 146
       , runRnSpliceHook        :: !(Maybe (HsUntypedSplice GhcRn -> RnM (HsUntypedSplice GhcRn)))
    
    147 147
       , getValueSafelyHook     :: !(Maybe (HscEnv -> Name -> Type
    
    148
    -                                         -> IO (Either Type (HValue, [Linkable], PkgsLoaded))))
    
    148
    +                                         -> IO (Either Type (HValue, [LinkableUsage], PkgsLoaded))))
    
    149 149
       , createIservProcessHook :: !(Maybe (CreateProcess -> IO ProcessHandle))
    
    150 150
       , stgToCmmHook           :: !(Maybe (StgToCmmConfig -> InfoTableProvMap -> [TyCon] -> CollectedCCs
    
    151 151
                                      -> [CgStgTopBinding] -> CgStream CmmGroup ModuleLFInfos))
    

  • compiler/GHC/Driver/Main.hs
    ... ... @@ -297,8 +297,7 @@ import GHC.Cmm.Config (CmmConfig)
    297 297
     import Data.Bifunctor
    
    298 298
     import qualified GHC.Unit.Home.Graph as HUG
    
    299 299
     import GHC.Unit.Home.PackageTable
    
    300
    -
    
    301
    -import GHC.ByteCode.Serialize
    
    300
    +import qualified GHC.ByteCode.Serialize as ByteCode
    
    302 301
     
    
    303 302
     {- **********************************************************************
    
    304 303
     %*                                                                      *
    
    ... ... @@ -973,23 +972,22 @@ checkObjects dflags mb_old_linkable summary = do
    973 972
     -- | Check to see if we can reuse the old linkable, by this point we will
    
    974 973
     -- have just checked that the old interface matches up with the source hash, so
    
    975 974
     -- no need to check that again here
    
    976
    -checkByteCodeInMemory :: HscEnv -> ModSummary -> Maybe Linkable -> IO (MaybeValidated Linkable)
    
    975
    +checkByteCodeInMemory :: HscEnv -> ModSummary -> Maybe (LinkableWith ModuleByteCode) -> IO (MaybeValidated (LinkableWith ModuleByteCode))
    
    977 976
     checkByteCodeInMemory hsc_env mod_sum mb_old_linkable =
    
    978 977
       case mb_old_linkable of
    
    979 978
         Just old_linkable
    
    980
    -      | not (linkableIsNativeCodeOnly old_linkable)
    
    981 979
           -- If `-fwrite-byte-code` is enabled, then check that the .gbc file is
    
    982 980
           -- up-to-date with the linkable we have in our hand.
    
    983 981
           -- If ms_bytecode_date is Nothing, then the .gbc file does not exist yet.
    
    984 982
           -- Otherwise, check that the date matches the linkable date exactly.
    
    985
    -      , if gopt Opt_WriteByteCode (hsc_dflags hsc_env)
    
    983
    +      | if gopt Opt_WriteByteCode (hsc_dflags hsc_env)
    
    986 984
               then maybe False (linkableTime old_linkable ==) (ms_bytecode_date mod_sum)
    
    987 985
               else True
    
    988 986
           -> return $ (UpToDateItem old_linkable)
    
    989 987
         _ -> return $ outOfDateItemBecause MissingBytecode Nothing
    
    990 988
     
    
    991 989
     -- | Load bytecode from a ".gbc" object file if it exists and is up-to-date
    
    992
    -checkByteCodeFromObject :: HscEnv -> ModSummary -> IO (MaybeValidated Linkable)
    
    990
    +checkByteCodeFromObject :: HscEnv -> ModSummary -> IO (MaybeValidated (LinkableWith ModuleByteCode))
    
    993 991
     checkByteCodeFromObject hsc_env mod_sum = do
    
    994 992
       let
    
    995 993
         obj_fn = ml_bytecode_file (ms_location mod_sum)
    
    ... ... @@ -1001,8 +999,8 @@ checkByteCodeFromObject hsc_env mod_sum = do
    1001 999
               -- Don't force this if we reuse the linkable already loaded into memory, but we have to check
    
    1002 1000
               -- that the one we have on disk would be suitable as well.
    
    1003 1001
               linkable <- unsafeInterleaveIO $ do
    
    1004
    -            bco <- readBinByteCode hsc_env obj_fn
    
    1005
    -            return $ mkModuleByteCodeLinkable obj_date bco
    
    1002
    +            bco <- ByteCode.readBinByteCode hsc_env obj_fn
    
    1003
    +            return $ mkOnlyModuleByteCodeLinkable obj_date bco
    
    1006 1004
               return $ UpToDateItem linkable
    
    1007 1005
         _ -> return $ outOfDateItemBecause MissingBytecode Nothing
    
    1008 1006
     
    
    ... ... @@ -1086,7 +1084,7 @@ loadIfaceByteCodeLazy ::
    1086 1084
       ModIface ->
    
    1087 1085
       ModLocation ->
    
    1088 1086
       TypeEnv ->
    
    1089
    -  IO (Maybe Linkable)
    
    1087
    +  IO (Maybe (LinkableWith ModuleByteCode))
    
    1090 1088
     loadIfaceByteCodeLazy hsc_env iface location type_env =
    
    1091 1089
       case iface_core_bindings iface location of
    
    1092 1090
         Nothing -> return Nothing
    
    ... ... @@ -1094,8 +1092,9 @@ loadIfaceByteCodeLazy hsc_env iface location type_env =
    1094 1092
           Just <$> compile wcb
    
    1095 1093
       where
    
    1096 1094
         compile decls = do
    
    1097
    -      bco <- unsafeInterleaveIO $ compileWholeCoreBindings hsc_env type_env decls
    
    1098
    -      linkable $ NE.singleton (DotGBC bco)
    
    1095
    +      bco <- unsafeInterleaveIO $ do
    
    1096
    +          compileWholeCoreBindings hsc_env type_env decls
    
    1097
    +      linkable bco
    
    1099 1098
     
    
    1100 1099
         linkable parts = do
    
    1101 1100
           if_time <- modificationTimeIfExists (ml_hi_file_ospath location)
    
    ... ... @@ -1136,14 +1135,14 @@ initWholeCoreBindings hsc_env iface details (RecompLinkables bc o) = do
    1136 1135
       where
    
    1137 1136
         type_env = md_types details
    
    1138 1137
     
    
    1139
    -    go :: RecompBytecodeLinkable -> IO (Maybe Linkable)
    
    1138
    +    go :: RecompBytecodeLinkable -> IO (Maybe (LinkableWith ModuleByteCode))
    
    1140 1139
         go (NormalLinkable l) = pure l
    
    1141 1140
         go (WholeCoreBindingsLinkable wcbl) =
    
    1142 1141
           fmap Just $ for wcbl $ \wcb -> do
    
    1143 1142
             add_iface_to_hpt iface details hsc_env
    
    1144
    -        bco <- unsafeInterleaveIO $
    
    1145
    -                       compileWholeCoreBindings hsc_env type_env wcb
    
    1146
    -        pure $ NE.singleton (DotGBC bco)
    
    1143
    +        bco <- unsafeInterleaveIO $ do
    
    1144
    +            compileWholeCoreBindings hsc_env type_env wcb
    
    1145
    +        pure bco
    
    1147 1146
     
    
    1148 1147
     -- | Hydrate interface Core bindings and compile them to bytecode.
    
    1149 1148
     --
    
    ... ... @@ -2205,7 +2204,7 @@ generateAndWriteByteCode hsc_env cgguts mod_location = do
    2205 2204
       -- See Note [-fwrite-byte-code is not the default]
    
    2206 2205
       when (gopt Opt_WriteByteCode dflags) $ do
    
    2207 2206
         let bc_path = ml_bytecode_file mod_location
    
    2208
    -    writeBinByteCode bc_path comp_bc
    
    2207
    +    ByteCode.writeBinByteCode bc_path comp_bc
    
    2209 2208
       return comp_bc
    
    2210 2209
     
    
    2211 2210
     {-
    
    ... ... @@ -2220,20 +2219,20 @@ make user's opt into writing the files.
    2220 2219
     -}
    
    2221 2220
     
    
    2222 2221
     -- | Generate a 'ModuleByteCode' and write it to disk if `-fwrite-byte-code` is enabled.
    
    2223
    -generateAndWriteByteCodeLinkable :: HscEnv -> CgInteractiveGuts -> ModLocation -> IO Linkable
    
    2222
    +generateAndWriteByteCodeLinkable :: HscEnv -> CgInteractiveGuts -> ModLocation -> IO (LinkableWith ModuleByteCode)
    
    2224 2223
     generateAndWriteByteCodeLinkable hsc_env cgguts mod_location = do
    
    2225 2224
       bco_object <- generateAndWriteByteCode hsc_env cgguts mod_location
    
    2226 2225
       -- Either, get the same time as the .gbc file if it exists, or just the current time.
    
    2227 2226
       -- It's important the time of the linkable matches the time of the .gbc file for recompilation
    
    2228 2227
       -- checking.
    
    2229 2228
       bco_time <- maybe getCurrentTime pure =<< modificationTimeIfExists (ml_bytecode_file_ospath mod_location)
    
    2230
    -  return $ mkModuleByteCodeLinkable bco_time bco_object
    
    2229
    +  return $ mkOnlyModuleByteCodeLinkable bco_time bco_object
    
    2231 2230
     
    
    2232 2231
     mkModuleByteCode :: HscEnv -> Module -> ModLocation -> CgInteractiveGuts -> IO ModuleByteCode
    
    2233 2232
     mkModuleByteCode hsc_env mod mod_location cgguts = do
    
    2234 2233
       bcos <- hscGenerateByteCode hsc_env cgguts mod_location
    
    2235 2234
       objs <- outputAndCompileForeign hsc_env mod mod_location (cgi_foreign_files cgguts) (cgi_foreign cgguts)
    
    2236
    -  return $! ModuleByteCode mod bcos objs
    
    2235
    +  ByteCode.mkModuleByteCode mod bcos objs
    
    2237 2236
     
    
    2238 2237
     -- | Generate a fresh 'ModuleByteCode' for a given module but do not write it to disk.
    
    2239 2238
     generateFreshByteCodeLinkable :: HscEnv
    
    ... ... @@ -2755,13 +2754,13 @@ hscTidy hsc_env guts = do
    2755 2754
     %*                                                                      *
    
    2756 2755
     %********************************************************************* -}
    
    2757 2756
     
    
    2758
    -hscCompileCoreExpr :: HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [Linkable], PkgsLoaded)
    
    2757
    +hscCompileCoreExpr :: HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [LinkableUsage], PkgsLoaded)
    
    2759 2758
     hscCompileCoreExpr hsc_env loc expr =
    
    2760 2759
       case hscCompileCoreExprHook (hsc_hooks hsc_env) of
    
    2761 2760
           Nothing -> hscCompileCoreExpr' hsc_env loc expr
    
    2762 2761
           Just h  -> h                   hsc_env loc expr
    
    2763 2762
     
    
    2764
    -hscCompileCoreExpr' :: HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [Linkable], PkgsLoaded)
    
    2763
    +hscCompileCoreExpr' :: HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [LinkableUsage], PkgsLoaded)
    
    2765 2764
     hscCompileCoreExpr' hsc_env srcspan ds_expr = do
    
    2766 2765
       {- Simplify it -}
    
    2767 2766
       -- Question: should we call SimpleOpt.simpleOptExpr here instead?
    
    ... ... @@ -2847,8 +2846,9 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do
    2847 2846
     
    
    2848 2847
           {- load it -}
    
    2849 2848
           bco_time <- getCurrentTime
    
    2849
    +      mbc <- ByteCode.mkModuleByteCode this_mod bcos []
    
    2850 2850
           (mods_needed, units_needed) <- loadDecls interp hsc_env srcspan $
    
    2851
    -        Linkable bco_time this_mod $ NE.singleton $ DotGBC (ModuleByteCode this_mod bcos [])
    
    2851
    +        Linkable bco_time this_mod $ NE.singleton (DotGBC mbc)
    
    2852 2852
           -- Get the foreign reference to the name we should have just loaded.
    
    2853 2853
           mhvs <- lookupFromLoadedEnv interp (idName binding_id)
    
    2854 2854
           {- Get the HValue for the root -}
    
    ... ... @@ -2864,7 +2864,7 @@ jsCodeGen
    2864 2864
       -> Module
    
    2865 2865
       -> [(CgStgTopBinding,IdSet)]
    
    2866 2866
       -> Id
    
    2867
    -  -> IO (ForeignHValue, [Linkable], PkgsLoaded)
    
    2867
    +  -> IO (ForeignHValue, [LinkableUsage], PkgsLoaded)
    
    2868 2868
     jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id = do
    
    2869 2869
       let logger           = hsc_logger hsc_env
    
    2870 2870
           tmpfs            = hsc_tmpfs hsc_env
    

  • compiler/GHC/Driver/Pipeline.hs
    ... ... @@ -430,7 +430,7 @@ link' hsc_env batch_attempt_linking mHscMessager hpt
    430 430
                     let obj_files = concatMap linkableObjs linkables
    
    431 431
                     in action obj_files
    
    432 432
                 linkBytecodeLinkable action =
    
    433
    -              checkLinkablesUpToDate hsc_env mHscMessager home_mods pkg_deps staticLink checkBytecodeLibraryLinkingNeeded homeMod_bytecode $ \linkables ->
    
    433
    +              checkLinkablesUpToDate hsc_env mHscMessager home_mods pkg_deps staticLink checkBytecodeLibraryLinkingNeeded homeModLinkableByteCode $ \linkables ->
    
    434 434
                     let bytecode = concatMap linkableModuleByteCodes linkables
    
    435 435
                     in action bytecode
    
    436 436
     
    

  • compiler/GHC/Driver/Plugins.hs
    ... ... @@ -342,7 +342,7 @@ data Plugins = Plugins
    342 342
           -- The purpose of this field is to cache the plugins so they
    
    343 343
           -- don't have to be loaded each time they are needed.  See
    
    344 344
           -- 'GHC.Runtime.Loader.initializePlugins'.
    
    345
    -  , loadedPluginDeps :: !([Linkable], PkgsLoaded)
    
    345
    +  , loadedPluginDeps :: !([LinkableUsage], PkgsLoaded)
    
    346 346
       -- ^ The object files required by the loaded plugins
    
    347 347
       -- See Note [Plugin dependencies]
    
    348 348
       }
    

  • compiler/GHC/HsToCore/Usage.hs
    ... ... @@ -7,8 +7,6 @@ module GHC.HsToCore.Usage (
    7 7
     
    
    8 8
     import GHC.Prelude
    
    9 9
     
    
    10
    -import GHC.Driver.Env
    
    11
    -
    
    12 10
     import GHC.Tc.Types
    
    13 11
     
    
    14 12
     import GHC.Iface.Load
    
    ... ... @@ -27,7 +25,6 @@ import GHC.Types.Unique.Set
    27 25
     
    
    28 26
     import GHC.Unit
    
    29 27
     import GHC.Unit.Env
    
    30
    -import GHC.Unit.External
    
    31 28
     import GHC.Unit.Module.Imported
    
    32 29
     import GHC.Unit.Module.ModIface
    
    33 30
     import GHC.Unit.Module.Deps
    
    ... ... @@ -35,18 +32,17 @@ import GHC.Unit.Module.Deps
    35 32
     import GHC.Data.Maybe
    
    36 33
     import GHC.Data.FastString
    
    37 34
     
    
    38
    -import Data.IORef
    
    39 35
     import Data.List (sortBy)
    
    40 36
     import Data.Map (Map)
    
    41 37
     import qualified Data.Map as Map
    
    42 38
     import qualified Data.Set as Set
    
    43
    -import qualified Data.List.NonEmpty as NE
    
    44 39
     
    
    45 40
     import GHC.Linker.Types
    
    46 41
     import GHC.Unit.Finder
    
    47 42
     import GHC.Types.Unique.DFM
    
    48 43
     import GHC.Driver.Plugins
    
    49 44
     import qualified GHC.Unit.Home.Graph as HUG
    
    45
    +import qualified Data.List.NonEmpty as NE
    
    50 46
     
    
    51 47
     {- Note [Module self-dependency]
    
    52 48
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -75,19 +71,17 @@ data UsageConfig = UsageConfig
    75 71
     
    
    76 72
     mkUsageInfo :: UsageConfig -> Plugins -> FinderCache -> UnitEnv
    
    77 73
                 -> Module -> ImportedMods -> [ImportUserSpec] -> NameSet
    
    78
    -            -> [FilePath] -> [FilePath] -> [(Module, Fingerprint)] -> [Linkable] -> PkgsLoaded
    
    74
    +            -> [FilePath] -> [FilePath] -> [(Module, Fingerprint)] -> [LinkableUsage] -> PkgsLoaded
    
    79 75
                 -> IfG [Usage]
    
    80 76
     mkUsageInfo uc plugins fc unit_env
    
    81 77
       this_mod dir_imp_mods imp_decls used_names
    
    82 78
       dependent_files dependent_dirs merged needed_links needed_pkgs
    
    83 79
       = do
    
    84
    -    eps <- liftIO $ readIORef (euc_eps (ue_eps unit_env))
    
    85 80
         file_hashes <- liftIO $ mapM getFileHash dependent_files
    
    86 81
         dirs_hashes <- liftIO $ mapM getDirHash dependent_dirs
    
    87 82
         let hu = ue_unsafeHomeUnit unit_env
    
    88
    -        hug = ue_home_unit_graph unit_env
    
    89 83
         -- Dependencies on object files due to TH and plugins
    
    90
    -    object_usages <- liftIO $ mkObjectUsage (eps_PIT eps) plugins fc hug needed_links needed_pkgs
    
    84
    +    object_usages <- liftIO $ mkObjectUsage plugins fc needed_links needed_pkgs
    
    91 85
         let all_home_ids = HUG.allUnits (ue_home_unit_graph unit_env)
    
    92 86
         mod_usages <- mk_mod_usage_info uc hu all_home_ids this_mod
    
    93 87
                                            dir_imp_mods imp_decls used_names
    
    ... ... @@ -176,44 +170,39 @@ For bytecode objects there are also two forms of dependencies.
    176 170
     1. The existence of the .gbc file for the module you are currently compiling.
    
    177 171
     2. The usage of bytecode to evaluate TH splices (similar to Note [Object File Dependencies])
    
    178 172
     
    
    179
    -In situation (2), we would ideally want to record the hash of the `CompiledByteCode` which
    
    180
    -was used when evaluating the TH splice. This was a bit tricky to implement so it's tracked as a future
    
    181
    -improvement to the recompilation checking for bytecode objects.
    
    182
    -
    
    183
    -For now, the interface hash is used as a proxy to determine if the BCO will have changed
    
    184
    -for a module or not. This is similar to how the recompilation checking for the legacy
    
    185
    -`-fwrite-if-simplified-core` code path which generated bytecode from core bindings used to work.
    
    186
    -
    
    173
    +In both cases, we record the hash of the 'CompiledByteCode' which was used when evaluating
    
    174
    +the TH splice.
    
    187 175
     -}
    
    188 176
     
    
    189 177
     
    
    190 178
     
    
    191 179
     -- | Find object files corresponding to the transitive closure of given home
    
    192 180
     -- modules and direct object files for pkg dependencies
    
    193
    -mkObjectUsage :: PackageIfaceTable -> Plugins -> FinderCache -> HomeUnitGraph-> [Linkable] -> PkgsLoaded -> IO [Usage]
    
    194
    -mkObjectUsage pit plugins fc hug th_links_needed th_pkgs_needed = do
    
    181
    +mkObjectUsage :: Plugins -> FinderCache -> [LinkableUsage] -> PkgsLoaded -> IO [Usage]
    
    182
    +mkObjectUsage plugins fc th_links_needed th_pkgs_needed = do
    
    195 183
           let ls = ordNubOn linkableModule (th_links_needed ++ plugins_links_needed)
    
    196 184
               ds = concatMap loaded_pkg_hs_objs $ eltsUDFM (plusUDFM th_pkgs_needed plugin_pkgs_needed) -- TODO possibly record loaded_pkg_non_hs_objs as well
    
    197 185
               (plugins_links_needed, plugin_pkgs_needed) = loadedPluginDeps plugins
    
    198 186
           concat <$> sequence (map linkableToUsage ls ++ map librarySpecToUsage ds)
    
    199 187
       where
    
    200
    -    linkableToUsage (Linkable _ m uls) = mapM (partToUsage m) (NE.toList uls)
    
    188
    +    linkableToUsage (Linkable _ _m parts) = traverse partToUsage (NE.toList parts)
    
    201 189
     
    
    202 190
         msg m = moduleNameString (moduleName m) ++ "[TH] changed"
    
    203 191
     
    
    204
    -    fing mmsg fn = UsageFile (mkFastString fn) <$> lookupFileCache fc fn <*> pure mmsg
    
    192
    +    partToUsage link_usage =
    
    193
    +      case link_usage of
    
    194
    +        FileLinkablePartUsage{flu_file, flu_module} -> do
    
    195
    +          fing (Just $ msg flu_module) flu_file
    
    205 196
     
    
    206
    -    partToUsage m part =
    
    207
    -      case linkablePartPath part of
    
    208
    -        Just fn -> fing (Just (msg m)) fn
    
    209
    -        Nothing ->  do
    
    210
    -          -- This should only happen for home package things but oneshot puts
    
    211
    -          -- home package ifaces in the PIT.
    
    212
    -          miface <- lookupIfaceByModule hug pit m
    
    213
    -          case miface of
    
    214
    -            Nothing -> pprPanic "linkableToUsage" (ppr m)
    
    215
    -            Just iface ->
    
    216
    -              return $ UsageHomeModuleInterface (moduleName m) (toUnitId $ moduleUnit m) (mi_iface_hash iface)
    
    197
    +        ByteCodeLinkablePartUsage{bclu_module, bclu_hash} ->
    
    198
    +          pure $
    
    199
    +            UsageHomeModuleBytecode
    
    200
    +              { usg_mod_name = moduleName bclu_module
    
    201
    +              , usg_unit_id = toUnitId $ moduleUnit bclu_module
    
    202
    +              , usg_bytecode_hash = bclu_hash
    
    203
    +              }
    
    204
    +
    
    205
    +    fing mmsg fn = UsageFile (mkFastString fn) <$> lookupFileCache fc fn <*> pure mmsg
    
    217 206
     
    
    218 207
         librarySpecToUsage :: LibrarySpec -> IO [Usage]
    
    219 208
         librarySpecToUsage (Objects os) = traverse (fing Nothing) os
    

  • compiler/GHC/Iface/Recomp.hs
    ... ... @@ -88,6 +88,10 @@ import GHC.Iface.Errors.Ppr
    88 88
     import Data.Functor
    
    89 89
     import Data.Bifunctor (first)
    
    90 90
     import GHC.Types.PkgQual
    
    91
    +import GHC.ByteCode.Serialize (ModuleByteCode, gbc_hash)
    
    92
    +import GHC.Unit.Home.Graph (lookupHugByModule)
    
    93
    +import GHC.Unit.Home.ModInfo (HomeModLinkable(..), HomeModInfo (..))
    
    94
    +import GHC.Linker.Types (linkableParts)
    
    91 95
     
    
    92 96
     {-
    
    93 97
       -----------------------------------------------
    
    ... ... @@ -190,6 +194,7 @@ data RecompReason
    190 194
       | ModuleAdded (ImportLevel, UnitId, ModuleName)
    
    191 195
       | ModuleChangedRaw ModuleName
    
    192 196
       | ModuleChangedIface ModuleName
    
    197
    +  | ModuleChangedBytecode ModuleName
    
    193 198
       | FileChanged FilePath
    
    194 199
       | DirChanged FilePath
    
    195 200
       | CustomReason String
    
    ... ... @@ -224,6 +229,7 @@ instance Outputable RecompReason where
    224 229
         ModuleChanged m          -> ppr m <+> text "changed"
    
    225 230
         ModuleChangedRaw m       -> ppr m <+> text "changed (raw)"
    
    226 231
         ModuleChangedIface m     -> ppr m <+> text "changed (interface)"
    
    232
    +    ModuleChangedBytecode m     -> ppr m <+> text "changed (bytecode)"
    
    227 233
         ModuleRemoved (_st, _uid, m)   -> ppr m <+> text "removed"
    
    228 234
         ModuleAdded (_st, _uid, m)     -> ppr m <+> text "added"
    
    229 235
         FileChanged fp           -> text fp <+> text "changed"
    
    ... ... @@ -716,6 +722,15 @@ needInterface mod continue
    716 722
             Nothing -> return $ NeedsRecompile MustCompile
    
    717 723
             Just iface -> liftIO $ continue iface
    
    718 724
     
    
    725
    +needBytecode :: Module -> (ModuleByteCode -> IO RecompileRequired)
    
    726
    +             -> IfG RecompileRequired
    
    727
    +needBytecode mod continue
    
    728
    +  = do
    
    729
    +      mb_recomp <- tryGetBytecode mod
    
    730
    +      case mb_recomp of
    
    731
    +        Nothing -> return $ NeedsRecompile MustCompile
    
    732
    +        Just mbc -> liftIO $ continue mbc
    
    733
    +
    
    719 734
     tryGetModIface :: String -> Module -> IfG (Maybe ModIface)
    
    720 735
     tryGetModIface doc_msg mod
    
    721 736
       = do  -- Load the imported interface if possible
    
    ... ... @@ -737,6 +752,27 @@ tryGetModIface doc_msg mod
    737 752
                       -- import and it's been deleted
    
    738 753
           Succeeded iface -> pure $ Just iface
    
    739 754
     
    
    755
    +tryGetBytecode :: Module -> IfG (Maybe ModuleByteCode)
    
    756
    +tryGetBytecode mod
    
    757
    +  = do  -- Load the imported bytecode if possible
    
    758
    +    logger <- getLogger
    
    759
    +    liftIO $ trace_hi_diffs logger (text "Checking bytecode hash for module" <+> ppr mod <+> ppr (moduleUnit mod))
    
    760
    +
    
    761
    +    mb_module_bytecode <- do
    
    762
    +      env <- getTopEnv
    
    763
    +      liftIO (lookupHugByModule mod (hsc_HUG env)) >>= \ case
    
    764
    +        Nothing -> pure Nothing
    
    765
    +        Just hmi ->
    
    766
    +          case homeMod_bytecode (hm_linkable hmi) of
    
    767
    +            Nothing -> pure Nothing
    
    768
    +            Just gbc_linkable -> pure $ Just $ linkableParts gbc_linkable
    
    769
    +
    
    770
    +    case mb_module_bytecode of
    
    771
    +      Nothing -> do
    
    772
    +        liftIO $ trace_hi_diffs logger (sep [text "Couldn't find bytecode for module", ppr mod])
    
    773
    +        return Nothing
    
    774
    +      Just module_bytecode -> pure $ Just module_bytecode
    
    775
    +
    
    740 776
     -- | Given the usage information extracted from the old
    
    741 777
     -- M.hi file for the module being compiled, figure out
    
    742 778
     -- whether M needs to be recompiled.
    
    ... ... @@ -758,14 +794,14 @@ checkModUsage _ UsageMergedRequirement{ usg_mod = mod, usg_mod_hash = old_mod_ha
    758 794
       needInterface mod $ \iface -> do
    
    759 795
         let reason = ModuleChangedRaw (moduleName mod)
    
    760 796
         checkModuleFingerprint logger reason old_mod_hash (mi_mod_hash iface)
    
    761
    -checkModUsage _  UsageHomeModuleInterface{ usg_mod_name = mod_name
    
    797
    +checkModUsage _  UsageHomeModuleBytecode{ usg_mod_name = mod_name
    
    762 798
                                                      , usg_unit_id = uid
    
    763
    -                                                 , usg_iface_hash = old_mod_hash } = do
    
    799
    +                                                 , usg_bytecode_hash = old_bytecode_hash } = do
    
    764 800
       let mod = mkModule (RealUnit (Definite uid)) mod_name
    
    765 801
       logger <- getLogger
    
    766
    -  needInterface mod $ \iface -> do
    
    767
    -    let reason = ModuleChangedIface mod_name
    
    768
    -    checkIfaceFingerprint logger reason old_mod_hash (mi_iface_hash iface)
    
    802
    +  needBytecode mod $ \cbc -> do
    
    803
    +    let reason = ModuleChangedBytecode mod_name
    
    804
    +    checkBytecodeFingerprint logger reason old_bytecode_hash (gbc_hash cbc)
    
    769 805
     
    
    770 806
     checkModUsage _ UsageHomeModule{
    
    771 807
                                     usg_mod_name = mod_name,
    
    ... ... @@ -1030,19 +1066,18 @@ checkModuleFingerprint logger reason old_mod_hash new_mod_hash
    1030 1066
       = out_of_date_hash logger reason (text "  Module fingerprint has changed")
    
    1031 1067
                          old_mod_hash new_mod_hash
    
    1032 1068
     
    
    1033
    -checkIfaceFingerprint
    
    1069
    +checkBytecodeFingerprint
    
    1034 1070
       :: Logger
    
    1035 1071
       -> RecompReason
    
    1036 1072
       -> Fingerprint
    
    1037 1073
       -> Fingerprint
    
    1038 1074
       -> IO RecompileRequired
    
    1039
    -checkIfaceFingerprint logger reason old_mod_hash new_mod_hash
    
    1040
    -  | new_mod_hash == old_mod_hash
    
    1041
    -  = up_to_date logger (text "Iface fingerprint unchanged")
    
    1042
    -
    
    1075
    +checkBytecodeFingerprint logger reason old_bytecode_hash new_bytecode_hash
    
    1076
    +  | old_bytecode_hash == new_bytecode_hash
    
    1077
    +  = up_to_date logger (text "Bytecode fingerprint unchanged")
    
    1043 1078
       | otherwise
    
    1044
    -  = out_of_date_hash logger reason (text "  Iface fingerprint has changed")
    
    1045
    -                     old_mod_hash new_mod_hash
    
    1079
    +  = out_of_date_hash logger reason (text "  Bytecode fingerprint has changed")
    
    1080
    +                     old_bytecode_hash new_bytecode_hash
    
    1046 1081
     
    
    1047 1082
     ------------------------
    
    1048 1083
     checkEntityUsage :: Logger
    

  • compiler/GHC/Iface/Recomp/Types.hs
    ... ... @@ -146,10 +146,10 @@ pprUsage usage@UsageDirectory{}
    146 146
               ppr (usg_dir_hash usage)]
    
    147 147
     pprUsage usage@UsageMergedRequirement{}
    
    148 148
       = hsep [text "merged", ppr (usg_mod usage), ppr (usg_mod_hash usage)]
    
    149
    -pprUsage usage@UsageHomeModuleInterface{}
    
    150
    -  = hsep [text "implementation", ppr (usg_mod_name usage)
    
    149
    +pprUsage usage@UsageHomeModuleBytecode{}
    
    150
    +  = hsep [text "Bytecode", ppr (usg_mod_name usage)
    
    151 151
                                    , ppr (usg_unit_id usage)
    
    152
    -                               , ppr (usg_iface_hash usage)]
    
    152
    +                               , ppr (usg_bytecode_hash usage)]
    
    153 153
     
    
    154 154
     pprUsageImport :: Outputable mod => mod -> Fingerprint -> IsSafeImport -> SDoc
    
    155 155
     pprUsageImport mod hash safe
    
    ... ... @@ -157,4 +157,4 @@ pprUsageImport mod hash safe
    157 157
              , ppr hash ]
    
    158 158
         where
    
    159 159
             pp_safe | safe      = text "safe"
    
    160
    -                | otherwise = text " -/ "
    \ No newline at end of file
    160
    +                | otherwise = text " -/ "

  • compiler/GHC/Linker/ByteCode.hs
    ... ... @@ -31,7 +31,7 @@ linkBytecodeLib hsc_env gbcs = do
    31 31
     
    
    32 32
       on_disk_bcos <- mapM (readBinByteCode hsc_env) bytecodeObjects
    
    33 33
     
    
    34
    -  let (all_cbcs, foreign_stubs) = unzip [ (bs, fs) | ModuleByteCode _m bs fs <- on_disk_bcos ++ gbcs]
    
    34
    +  let (all_cbcs, foreign_stubs) = unzip [ (bs, fs) | ModuleByteCode _m bs fs _hash <- on_disk_bcos ++ gbcs]
    
    35 35
     
    
    36 36
       interpreter_foreign_lib <- mkInterpreterLib hsc_env (concat foreign_stubs ++ objectFiles)
    
    37 37
     
    
    ... ... @@ -67,4 +67,4 @@ mkInterpreterLib hsc_env files =
    67 67
               return $ Just (InterpreterSharedObject foreign_stub_lib_path foreign_stub_lib_dir foreign_stub_lib_name)
    
    68 68
             Nothing -> pure Nothing
    
    69 69
         False -> do
    
    70
    -      pure $ Just (InterpreterStaticObjects files)
    \ No newline at end of file
    70
    +      pure $ Just (InterpreterStaticObjects files)

  • compiler/GHC/Linker/Deps.hs
    ... ... @@ -63,7 +63,7 @@ data LinkDepsOpts = LinkDepsOpts
    63 63
     
    
    64 64
     data LinkDeps = LinkDeps
    
    65 65
       { ldNeededLinkables :: [Linkable]
    
    66
    -  , ldAllLinkables    :: [Linkable]
    
    66
    +  , ldAllLinkables    :: [LinkableUsage]
    
    67 67
       , ldUnits           :: [UnitId]
    
    68 68
       , ldNeededUnits     :: UniqDSet UnitId
    
    69 69
       }
    
    ... ... @@ -126,7 +126,7 @@ get_link_deps opts pls maybe_normal_osuf span mods = do
    126 126
     
    
    127 127
           return $ LinkDeps
    
    128 128
             { ldNeededLinkables = lnks_needed
    
    129
    -        , ldAllLinkables    = links_got ++ lnks_needed
    
    129
    +        , ldAllLinkables    = links_got ++ mkLinkablesUsage lnks_needed
    
    130 130
             , ldUnits           = pkgs_needed
    
    131 131
             , ldNeededUnits     = pkgs_s
    
    132 132
             }
    

  • compiler/GHC/Linker/Loader.hs
    ... ... @@ -230,7 +230,7 @@ lookupFromLoadedEnv interp name = do
    230 230
     -- | Load the module containing the given Name and get its associated 'HValue'.
    
    231 231
     --
    
    232 232
     -- Throws a 'ProgramError' if loading fails or the name cannot be found.
    
    233
    -loadName :: Interp -> HscEnv -> Name -> IO (ForeignHValue, [Linkable], PkgsLoaded)
    
    233
    +loadName :: Interp -> HscEnv -> Name -> IO (ForeignHValue, [LinkableUsage], PkgsLoaded)
    
    234 234
     loadName interp hsc_env name = do
    
    235 235
       initLoaderState interp hsc_env
    
    236 236
       modifyLoaderState interp $ \pls0 -> do
    
    ... ... @@ -274,7 +274,7 @@ loadDependencies
    274 274
       -> LoaderState
    
    275 275
       -> SrcSpan
    
    276 276
       -> [Module]
    
    277
    -  -> IO (LoaderState, SuccessFlag, [Linkable], PkgsLoaded) -- ^ returns the set of linkables required
    
    277
    +  -> IO (LoaderState, SuccessFlag, [LinkableUsage], PkgsLoaded) -- ^ returns the set of linkables required
    
    278 278
     -- When called, the loader state must have been initialized (see `initLoaderState`)
    
    279 279
     loadDependencies interp hsc_env pls span needed_mods = do
    
    280 280
        let opts = initLinkDepsOpts hsc_env
    
    ... ... @@ -656,7 +656,7 @@ initLinkDepsOpts hsc_env = opts
    656 656
         dflags = hsc_dflags hsc_env
    
    657 657
     
    
    658 658
         ldLoadByteCode mod locn = do
    
    659
    -      bytecode_linkable <-  findBytecodeLinkableMaybe hsc_env mod locn
    
    659
    +      bytecode_linkable <-  findBytecodeLinkableMaybe hsc_env locn
    
    660 660
           case bytecode_linkable of
    
    661 661
             Nothing -> findWholeCoreBindings hsc_env mod
    
    662 662
             Just bco -> return (Just bco)
    
    ... ... @@ -670,19 +670,14 @@ findWholeCoreBindings hsc_env mod = do
    670 670
           sequence (lookupModuleEnv eps_iface_bytecode mod)
    
    671 671
     
    
    672 672
     
    
    673
    -findBytecodeLinkableMaybe :: HscEnv -> Module -> ModLocation -> IO (Maybe Linkable)
    
    674
    -findBytecodeLinkableMaybe hsc_env mod locn = do
    
    673
    +findBytecodeLinkableMaybe :: HscEnv -> ModLocation -> IO (Maybe Linkable)
    
    674
    +findBytecodeLinkableMaybe hsc_env locn = do
    
    675 675
       let bytecode_fn    = ml_bytecode_file locn
    
    676 676
           bytecode_fn_os = ml_bytecode_file_ospath locn
    
    677 677
       maybe_bytecode_time <- modificationTimeIfExists bytecode_fn_os
    
    678 678
       case maybe_bytecode_time of
    
    679 679
         Nothing -> return Nothing
    
    680 680
         Just bytecode_time -> do
    
    681
    -      -- Also load the interface, for reasons to do with recompilation avoidance.
    
    682
    -      -- See Note [Recompilation avoidance with bytecode objects]
    
    683
    -      _ <- initIfaceLoad hsc_env $
    
    684
    -             loadInterface (text "get_reachable_nodes" <+> parens (ppr mod))
    
    685
    -                 mod ImportBySystem
    
    686 681
           bco <- readBinByteCode hsc_env bytecode_fn
    
    687 682
           return $ Just $ mkModuleByteCodeLinkable bytecode_time bco
    
    688 683
     
    
    ... ... @@ -734,7 +729,7 @@ get_reachable_nodes hsc_env mods
    734 729
       ********************************************************************* -}
    
    735 730
     
    
    736 731
     -- | Load the dependencies of a linkable, and then load the linkable itself.
    
    737
    -loadDecls :: Interp -> HscEnv -> SrcSpan -> Linkable -> IO ([Linkable], PkgsLoaded)
    
    732
    +loadDecls :: Interp -> HscEnv -> SrcSpan -> Linkable -> IO ([LinkableUsage], PkgsLoaded)
    
    738 733
     loadDecls interp hsc_env span linkable = do
    
    739 734
         -- Initialise the linker (if it's not been done already)
    
    740 735
         initLoaderState interp hsc_env
    
    ... ... @@ -834,7 +829,7 @@ loadModuleLinkables interp hsc_env pls keep_spec linkables
    834 829
         (objs, bcos) = partitionLinkables linkables
    
    835 830
     
    
    836 831
     
    
    837
    -linkableInSet :: Linkable -> LinkableSet -> Bool
    
    832
    +linkableInSet :: Linkable -> LinkableSet LinkableUsage -> Bool
    
    838 833
     linkableInSet l objs_loaded =
    
    839 834
       case lookupModuleEnv objs_loaded (linkableModule l) of
    
    840 835
             Nothing -> False
    
    ... ... @@ -963,17 +958,17 @@ dynLoadObjs interp hsc_env pls objs = do
    963 958
                             then addWay WayProf
    
    964 959
                             else id
    
    965 960
     
    
    966
    -rmDupLinkables :: LinkableSet    -- Already loaded
    
    967
    -               -> [Linkable]    -- New linkables
    
    968
    -               -> (LinkableSet,  -- New loaded set (including new ones)
    
    961
    +rmDupLinkables :: LinkableSet LinkableUsage  -- ^ Already loaded
    
    962
    +               -> [Linkable]    -- ^ New linkables
    
    963
    +               -> (LinkableSet LinkableUsage,  -- New loaded set (including new ones)
    
    969 964
                        [Linkable])  -- New linkables (excluding dups)
    
    970 965
     rmDupLinkables already ls
    
    971 966
       = go already [] ls
    
    972 967
       where
    
    973
    -    go already extras [] = (already, extras)
    
    974
    -    go already extras (l:ls)
    
    968
    +    go !already extras [] = (already, extras)
    
    969
    +    go !already extras (l:ls)
    
    975 970
             | linkableInSet l already = go already     extras     ls
    
    976
    -        | otherwise               = go (extendModuleEnv already (linkableModule l) l) (l:extras) ls
    
    971
    +        | otherwise               = go (extendModuleEnv already (linkableModule l) $! mkLinkableUsage l) (l:extras) ls
    
    977 972
     
    
    978 973
     {- **********************************************************************
    
    979 974
     
    
    ... ... @@ -1126,7 +1121,7 @@ unload_wkr interp pls@LoaderState{..} = do
    1126 1121
     
    
    1127 1122
       -- If we unloaded any object files at all, we need to purge the cache
    
    1128 1123
       -- of lookupSymbol results.
    
    1129
    -  when (not (null (filter (not . null . linkableObjs) linkables_to_unload))) $
    
    1124
    +  when (not (null (filter (not . null . linkableUsageObjs) linkables_to_unload))) $
    
    1130 1125
         purgeLookupSymbolCache interp
    
    1131 1126
     
    
    1132 1127
       let !new_pls = pls { bco_loader_state = modifyHomePackageBytecodeState bco_loader_state $ \_ -> emptyBytecodeState,
    
    ... ... @@ -1136,7 +1131,7 @@ unload_wkr interp pls@LoaderState{..} = do
    1136 1131
     
    
    1137 1132
       return new_pls
    
    1138 1133
       where
    
    1139
    -    unloadObjs :: Linkable -> IO ()
    
    1134
    +    unloadObjs :: LinkableUsage -> IO ()
    
    1140 1135
         unloadObjs lnk
    
    1141 1136
           | interpreterDynamic interp = return ()
    
    1142 1137
             -- We don't do any cleanup when linking objects with the
    
    ... ... @@ -1144,7 +1139,7 @@ unload_wkr interp pls@LoaderState{..} = do
    1144 1139
             -- not much benefit.
    
    1145 1140
     
    
    1146 1141
           | otherwise
    
    1147
    -      = mapM_ (unloadObj interp) (linkableObjs lnk)
    
    1142
    +      = mapM_ (unloadObj interp) (linkableUsageObjs lnk)
    
    1148 1143
                     -- The components of a BCO linkable may contain
    
    1149 1144
                     -- dot-o files (generated from C stubs).
    
    1150 1145
                     --
    

  • compiler/GHC/Linker/Types.hs
    ... ... @@ -49,6 +49,7 @@ module GHC.Linker.Types
    49 49
        , WholeCoreBindingsLinkable
    
    50 50
        , LinkableWith(..)
    
    51 51
        , mkModuleByteCodeLinkable
    
    52
    +   , mkOnlyModuleByteCodeLinkable
    
    52 53
        , LinkablePart(..)
    
    53 54
        , LinkableObjectSort (..)
    
    54 55
        , linkableIsNativeCodeOnly
    
    ... ... @@ -67,6 +68,11 @@ module GHC.Linker.Types
    67 68
        , linkableFilterNative
    
    68 69
        , partitionLinkables
    
    69 70
     
    
    71
    +   , LinkableUsage
    
    72
    +   , linkableUsageObjs
    
    73
    +   , mkLinkablesUsage
    
    74
    +   , mkLinkableUsage
    
    75
    +
    
    70 76
        , ModuleByteCode(..)
    
    71 77
        )
    
    72 78
     where
    
    ... ... @@ -78,26 +84,29 @@ import GHCi.BreakArray
    78 84
     import GHCi.RemoteTypes
    
    79 85
     import GHCi.Message            ( LoadedDLL )
    
    80 86
     
    
    87
    +import qualified GHC.Data.OsPath as OsPath
    
    88
    +import qualified GHC.Data.FlatBag as FlatBag
    
    89
    +import GHC.Fingerprint (Fingerprint)
    
    81 90
     import GHC.Stack.CCS
    
    82 91
     import GHC.Types.Name.Env      ( NameEnv, emptyNameEnv, extendNameEnvList, lookupNameEnv )
    
    83 92
     import GHC.Types.Name          ( Name )
    
    84 93
     import GHC.Types.SptEntry
    
    94
    +import GHC.Types.Unique.DSet
    
    95
    +import GHC.Types.Unique.DFM
    
    96
    +import GHC.Unit.Module.Deps (LinkablePartUsage (..), linkablePartUsageObjectPaths)
    
    97
    +import GHC.Unit.Module.Env
    
    98
    +import GHC.Unit.Module.WholeCoreBindings
    
    85 99
     
    
    86 100
     import GHC.Utils.Outputable
    
    87 101
     
    
    102
    +import Control.Applicative ((<|>))
    
    88 103
     import Control.Concurrent.MVar
    
    89 104
     import Data.Array
    
    105
    +import Data.Functor.Identity
    
    90 106
     import Data.Time               ( UTCTime )
    
    91
    -import GHC.Unit.Module.Env
    
    92
    -import GHC.Types.Unique.DSet
    
    93
    -import GHC.Types.Unique.DFM
    
    94
    -import GHC.Unit.Module.WholeCoreBindings
    
    95 107
     import Data.Maybe (mapMaybe)
    
    96 108
     import Data.List.NonEmpty (NonEmpty, nonEmpty)
    
    97 109
     import qualified Data.List.NonEmpty as NE
    
    98
    -import Control.Applicative ((<|>))
    
    99
    -import Data.Functor.Identity
    
    100
    -
    
    101 110
     
    
    102 111
     {- **********************************************************************
    
    103 112
     
    
    ... ... @@ -172,10 +181,10 @@ data LoaderState = LoaderState
    172 181
             -- ^ Information about bytecode objects we have loaded into the
    
    173 182
             -- interpreter.
    
    174 183
     
    
    175
    -    , bcos_loaded :: !LinkableSet
    
    184
    +    , bcos_loaded :: !(LinkableSet LinkableUsage)
    
    176 185
             -- ^ The currently loaded interpreted modules (home package)
    
    177 186
     
    
    178
    -    , objs_loaded :: !LinkableSet
    
    187
    +    , objs_loaded :: !(LinkableSet LinkableUsage)
    
    179 188
             -- ^ And the currently-loaded compiled modules (home package)
    
    180 189
     
    
    181 190
         , pkgs_loaded :: !PkgsLoaded
    
    ... ... @@ -384,15 +393,17 @@ type Linkable = LinkableWith (NonEmpty LinkablePart)
    384 393
     
    
    385 394
     type WholeCoreBindingsLinkable = LinkableWith WholeCoreBindings
    
    386 395
     
    
    387
    -type LinkableSet = ModuleEnv Linkable
    
    396
    +type LinkableUsage = LinkableWith (NonEmpty LinkablePartUsage)
    
    388 397
     
    
    389
    -mkLinkableSet :: [Linkable] -> LinkableSet
    
    398
    +type LinkableSet = ModuleEnv
    
    399
    +
    
    400
    +mkLinkableSet :: [Linkable] -> LinkableSet Linkable
    
    390 401
     mkLinkableSet ls = mkModuleEnv [(linkableModule l, l) | l <- ls]
    
    391 402
     
    
    392 403
     -- | Union of LinkableSets.
    
    393 404
     --
    
    394 405
     -- In case of conflict, keep the most recent Linkable (as per linkableTime)
    
    395
    -unionLinkableSet :: LinkableSet -> LinkableSet -> LinkableSet
    
    406
    +unionLinkableSet :: LinkableSet (LinkableWith a) -> LinkableSet (LinkableWith a) -> LinkableSet (LinkableWith a)
    
    396 407
     unionLinkableSet = plusModuleEnv_C go
    
    397 408
       where
    
    398 409
         go l1 l2
    
    ... ... @@ -435,8 +446,9 @@ data LinkablePart
    435 446
       | DotDLL FilePath
    
    436 447
           -- ^ Dynamically linked library file (.so, .dll, .dylib)
    
    437 448
     
    
    438
    -  | DotGBC ModuleByteCode
    
    439
    -    -- ^ A byte-code object, lives only in memory.
    
    449
    +  | DotGBC
    
    450
    +      -- ^ A byte-code object, lives only in memory.
    
    451
    +      ModuleByteCode
    
    440 452
     
    
    441 453
     
    
    442 454
     -- | The in-memory representation of a bytecode object
    
    ... ... @@ -444,14 +456,19 @@ data LinkablePart
    444 456
     data ModuleByteCode = ModuleByteCode { gbc_module :: Module
    
    445 457
                                           , gbc_compiled_byte_code :: CompiledByteCode
    
    446 458
                                           , gbc_foreign_files :: [FilePath]  -- ^ Path to object files
    
    459
    +                                      , gbc_hash :: !Fingerprint
    
    447 460
                                           }
    
    448 461
     
    
    449 462
     mkModuleByteCodeLinkable :: UTCTime -> ModuleByteCode -> Linkable
    
    450
    -mkModuleByteCodeLinkable linkable_time bco =
    
    463
    +mkModuleByteCodeLinkable linkable_time bco = do
    
    451 464
       Linkable linkable_time (gbc_module bco) (pure (DotGBC bco))
    
    452 465
     
    
    466
    +mkOnlyModuleByteCodeLinkable :: UTCTime -> ModuleByteCode -> LinkableWith ModuleByteCode
    
    467
    +mkOnlyModuleByteCodeLinkable linkable_time bco = do
    
    468
    +  Linkable linkable_time (gbc_module bco) bco
    
    469
    +
    
    453 470
     instance Outputable ModuleByteCode where
    
    454
    -  ppr (ModuleByteCode mod _cbc _fos) = text "ModuleByteCode" <+> ppr mod
    
    471
    +  ppr (ModuleByteCode mod _cbc _fos _) = text "ModuleByteCode" <+> ppr mod
    
    455 472
     
    
    456 473
     instance Outputable LinkablePart where
    
    457 474
       ppr (DotO path sort)   = text "DotO" <+> text path <+> pprSort sort
    
    ... ... @@ -544,8 +561,8 @@ linkablePartObjectPaths = \case
    544 561
     -- Contrary to linkableBCOs, this includes byte-code from LazyBCOs.
    
    545 562
     linkablePartBCOs :: LinkablePart -> [CompiledByteCode]
    
    546 563
     linkablePartBCOs = \case
    
    547
    -  DotGBC bco    -> [gbc_compiled_byte_code bco]
    
    548
    -  _           -> []
    
    564
    +  DotGBC bco -> [gbc_compiled_byte_code bco]
    
    565
    +  _          -> []
    
    549 566
     
    
    550 567
     linkableFilter :: (LinkablePart -> [LinkablePart]) -> Linkable -> Maybe Linkable
    
    551 568
     linkableFilter f linkable = do
    
    ... ... @@ -586,6 +603,59 @@ partitionLinkables linkables =
    586 603
         mapMaybe linkableFilterByteCode linkables
    
    587 604
       )
    
    588 605
     
    
    606
    +-- | Turn a 'Linkable' into a 'LinkableUsage'.
    
    607
    +-- This stores much less information than 'Linkable' and allows us
    
    608
    +-- to free the fields of the 'Linkable'.
    
    609
    +--
    
    610
    +-- Each 'LinkablePartUsage' is fully evaluated to avoid retaining any reference
    
    611
    +-- to the original 'LinkablePart'.
    
    612
    +mkLinkableUsage :: Linkable -> LinkableUsage
    
    613
    +mkLinkableUsage lnk =
    
    614
    +  let
    
    615
    +    linkablesWithUsage = NE.map (go (linkableModule lnk)) (linkableParts lnk)
    
    616
    +    lnkUsage = lnk
    
    617
    +      { linkableParts =
    
    618
    +          -- We force the elements intentionally to whnf.
    
    619
    +          --
    
    620
    +          elemsToWhnf linkablesWithUsage `seq` linkablesWithUsage
    
    621
    +      }
    
    622
    +  in
    
    623
    +    linkableParts lnkUsage `seq` lnkUsage
    
    624
    +  where
    
    625
    +    -- Make sure 'LinkableUsagePart' is evaluated to whnf
    
    626
    +    elemsToWhnf :: NonEmpty a -> ()
    
    627
    +    elemsToWhnf = foldr seq ()
    
    628
    +
    
    629
    +
    
    630
    +    mkFileLinkablePartUsage m fp objs =
    
    631
    +      FileLinkablePartUsage
    
    632
    +        { flu_file = fp
    
    633
    +        , flu_module = m
    
    634
    +        , flu_linkable_objs =
    
    635
    +            FlatBag.fromList (strictGenericLength objs) [ OsPath.unsafeEncodeUtf obj | obj <- objs  ]
    
    636
    +        }
    
    637
    +
    
    638
    +    mkByteCodeLinkablePartUsage m fp objs =
    
    639
    +      ByteCodeLinkablePartUsage
    
    640
    +        { bclu_module = m
    
    641
    +        , bclu_hash = fp
    
    642
    +        , bclu_linkable_objs =
    
    643
    +            FlatBag.fromList (strictGenericLength objs) [ OsPath.unsafeEncodeUtf obj | obj <- objs  ]
    
    644
    +        }
    
    645
    +
    
    646
    +    go :: Module -> LinkablePart -> LinkablePartUsage
    
    647
    +    go m lnkPart = case lnkPart of
    
    648
    +      DotO fn _ -> mkFileLinkablePartUsage m fn (linkablePartObjectPaths lnkPart)
    
    649
    +      DotA fn -> mkFileLinkablePartUsage m fn (linkablePartObjectPaths lnkPart)
    
    650
    +      DotDLL fn -> mkFileLinkablePartUsage m fn (linkablePartObjectPaths lnkPart)
    
    651
    +      DotGBC mbc -> mkByteCodeLinkablePartUsage m (gbc_hash mbc) (linkablePartObjectPaths lnkPart)
    
    652
    +
    
    653
    +mkLinkablesUsage :: [Linkable] -> [LinkableUsage]
    
    654
    +mkLinkablesUsage linkables = map mkLinkableUsage linkables
    
    655
    +
    
    656
    +linkableUsageObjs :: LinkableUsage -> [FilePath]
    
    657
    +linkableUsageObjs lnkWithUsage = concatMap linkablePartUsageObjectPaths (linkableParts lnkWithUsage)
    
    658
    +
    
    589 659
     {- **********************************************************************
    
    590 660
     
    
    591 661
                     Loading packages
    

  • compiler/GHC/Runtime/Loader.hs
    ... ... @@ -153,7 +153,7 @@ initializePlugins hsc_env
    153 153
           ([]  , _ )  -> False -- some external plugin added
    
    154 154
           (p:ps,s:ss) -> check_external_plugin p s && check_external_plugins ps ss
    
    155 155
     
    
    156
    -loadPlugins :: HscEnv -> IO ([LoadedPlugin], [Linkable], PkgsLoaded)
    
    156
    +loadPlugins :: HscEnv -> IO ([LoadedPlugin], [LinkableUsage], PkgsLoaded)
    
    157 157
     loadPlugins hsc_env
    
    158 158
       = do { unless (null to_load) $
    
    159 159
                checkExternalInterpreter hsc_env
    
    ... ... @@ -173,7 +173,7 @@ loadPlugins hsc_env
    173 173
         loadPlugin = loadPlugin' (mkVarOccFS (fsLit "plugin")) pluginTyConName hsc_env
    
    174 174
     
    
    175 175
     
    
    176
    -loadFrontendPlugin :: HscEnv -> ModuleName -> IO (FrontendPlugin, [Linkable], PkgsLoaded)
    
    176
    +loadFrontendPlugin :: HscEnv -> ModuleName -> IO (FrontendPlugin, [LinkableUsage], PkgsLoaded)
    
    177 177
     loadFrontendPlugin hsc_env mod_name = do
    
    178 178
         checkExternalInterpreter hsc_env
    
    179 179
         (plugin, _iface, links, pkgs)
    
    ... ... @@ -188,7 +188,7 @@ checkExternalInterpreter hsc_env = case interpInstance <$> hsc_interp hsc_env of
    188 188
         -> throwIO (InstallationError "Plugins require -fno-external-interpreter")
    
    189 189
       _ -> pure ()
    
    190 190
     
    
    191
    -loadPlugin' :: OccName -> Name -> HscEnv -> ModuleName -> IO (a, ModIface, [Linkable], PkgsLoaded)
    
    191
    +loadPlugin' :: OccName -> Name -> HscEnv -> ModuleName -> IO (a, ModIface, [LinkableUsage], PkgsLoaded)
    
    192 192
     loadPlugin' occ_name plugin_name hsc_env mod_name
    
    193 193
       = do { let plugin_rdr_name = mkRdrQual mod_name occ_name
    
    194 194
                  dflags = hsc_dflags hsc_env
    
    ... ... @@ -266,7 +266,7 @@ forceLoadTyCon hsc_env con_name = do
    266 266
     -- * If the Name does not exist in the module
    
    267 267
     -- * If the link failed
    
    268 268
     
    
    269
    -getValueSafely :: HscEnv -> Name -> Type -> IO (Either Type (a, [Linkable], PkgsLoaded))
    
    269
    +getValueSafely :: HscEnv -> Name -> Type -> IO (Either Type (a, [LinkableUsage], PkgsLoaded))
    
    270 270
     getValueSafely hsc_env val_name expected_type = do
    
    271 271
       eith_hval <- case getValueSafelyHook hooks of
    
    272 272
         Nothing -> getHValueSafely interp hsc_env val_name expected_type
    
    ... ... @@ -281,7 +281,7 @@ getValueSafely hsc_env val_name expected_type = do
    281 281
         logger = hsc_logger hsc_env
    
    282 282
         hooks  = hsc_hooks hsc_env
    
    283 283
     
    
    284
    -getHValueSafely :: Interp -> HscEnv -> Name -> Type -> IO (Either Type (HValue, [Linkable], PkgsLoaded))
    
    284
    +getHValueSafely :: Interp -> HscEnv -> Name -> Type -> IO (Either Type (HValue, [LinkableUsage], PkgsLoaded))
    
    285 285
     getHValueSafely interp hsc_env val_name expected_type = do
    
    286 286
         forceLoadNameModuleInterface hsc_env (text "contains a name used in an invocation of getHValueSafely") val_name
    
    287 287
         -- Now look up the names for the value and type constructor in the type environment
    

  • compiler/GHC/Tc/Types.hs
    ... ... @@ -562,7 +562,7 @@ data TcGblEnv
    562 562
               -- is implicit rather than explicit, so we have to zap a
    
    563 563
               -- mutable variable.
    
    564 564
     
    
    565
    -        tcg_th_needed_deps :: TcRef ([Linkable], PkgsLoaded),
    
    565
    +        tcg_th_needed_deps :: TcRef ([LinkableUsage], PkgsLoaded),
    
    566 566
               -- ^ The set of runtime dependencies required by this module
    
    567 567
               -- See Note [Object File Dependencies]
    
    568 568
     
    

  • compiler/GHC/Tc/Utils/Monad.hs
    ... ... @@ -2259,7 +2259,7 @@ fillCoercionHole (CH { ch_ref = ref, ch_co_var = cv }) co
    2259 2259
     recordThUse :: TcM ()
    
    2260 2260
     recordThUse = do { env <- getGblEnv; writeTcRef (tcg_th_used env) True }
    
    2261 2261
     
    
    2262
    -recordThNeededRuntimeDeps :: [Linkable] -> PkgsLoaded -> TcM ()
    
    2262
    +recordThNeededRuntimeDeps :: [LinkableUsage] -> PkgsLoaded -> TcM ()
    
    2263 2263
     recordThNeededRuntimeDeps new_links new_pkgs
    
    2264 2264
       = do { env <- getGblEnv
    
    2265 2265
            ; updTcRef (tcg_th_needed_deps env) $ \(needed_links, needed_pkgs) ->
    

  • compiler/GHC/Unit/Home/ModInfo.hs
    ... ... @@ -3,9 +3,11 @@
    3 3
     module GHC.Unit.Home.ModInfo
    
    4 4
        (
    
    5 5
          HomeModInfo (..)
    
    6
    -   , HomeModLinkable (..)
    
    7 6
        , homeModInfoObject
    
    8 7
        , homeModInfoByteCode
    
    8
    +   , HomeModLinkable (..)
    
    9
    +   , homeModLinkableByteCode
    
    10
    +   , homeModLinkableObject
    
    9 11
        , emptyHomeModInfoLinkable
    
    10 12
        )
    
    11 13
     where
    
    ... ... @@ -15,9 +17,10 @@ import GHC.Prelude
    15 17
     import GHC.Unit.Module.ModIface
    
    16 18
     import GHC.Unit.Module.ModDetails
    
    17 19
     
    
    18
    -import GHC.Linker.Types ( Linkable )
    
    20
    +import GHC.Linker.Types ( Linkable, LinkableWith, ModuleByteCode, LinkablePart (..) )
    
    19 21
     
    
    20 22
     import GHC.Utils.Outputable
    
    23
    +import qualified Data.List.NonEmpty as NE
    
    21 24
     
    
    22 25
     -- | Information about modules in the package being compiled
    
    23 26
     data HomeModInfo = HomeModInfo
    
    ... ... @@ -48,18 +51,24 @@ data HomeModInfo = HomeModInfo
    48 51
        }
    
    49 52
     
    
    50 53
     homeModInfoByteCode :: HomeModInfo -> Maybe Linkable
    
    51
    -homeModInfoByteCode = homeMod_bytecode . hm_linkable
    
    54
    +homeModInfoByteCode = homeModLinkableByteCode . hm_linkable
    
    52 55
     
    
    53 56
     homeModInfoObject :: HomeModInfo -> Maybe Linkable
    
    54
    -homeModInfoObject = homeMod_object . hm_linkable
    
    57
    +homeModInfoObject = homeModLinkableObject . hm_linkable
    
    55 58
     
    
    56 59
     emptyHomeModInfoLinkable :: HomeModLinkable
    
    57 60
     emptyHomeModInfoLinkable = HomeModLinkable Nothing Nothing
    
    58 61
     
    
    59 62
     -- See Note [Home module build products]
    
    60
    -data HomeModLinkable = HomeModLinkable { homeMod_bytecode :: !(Maybe Linkable)
    
    63
    +data HomeModLinkable = HomeModLinkable { homeMod_bytecode :: !(Maybe (LinkableWith ModuleByteCode))
    
    61 64
                                            , homeMod_object   :: !(Maybe Linkable) }
    
    62 65
     
    
    66
    +homeModLinkableByteCode :: HomeModLinkable -> Maybe Linkable
    
    67
    +homeModLinkableByteCode = fmap (fmap (NE.singleton . DotGBC)) . homeMod_bytecode
    
    68
    +
    
    69
    +homeModLinkableObject :: HomeModLinkable -> Maybe Linkable
    
    70
    +homeModLinkableObject = homeMod_object
    
    71
    +
    
    63 72
     instance Outputable HomeModLinkable where
    
    64 73
       ppr (HomeModLinkable l1 l2) = ppr l1 $$ ppr l2
    
    65 74
     
    

  • compiler/GHC/Unit/Module/Deps.hs
    ... ... @@ -22,16 +22,22 @@ module GHC.Unit.Module.Deps
    22 22
        , ImportAvails (..)
    
    23 23
        , IfaceImportLevel(..)
    
    24 24
        , tcImportLevel
    
    25
    +   , LinkablePartUsage(..)
    
    26
    +   , linkablePartUsageObjectPaths
    
    25 27
        )
    
    26 28
     where
    
    27 29
     
    
    28 30
     import GHC.Prelude
    
    29 31
     
    
    30 32
     import GHC.Data.FastString
    
    33
    +import GHC.Data.FlatBag
    
    34
    +import GHC.Data.OsPath
    
    35
    +import qualified GHC.Data.OsPath as OsPath
    
    31 36
     
    
    32 37
     import GHC.Types.Avail
    
    33 38
     import GHC.Types.SafeHaskell
    
    34 39
     import GHC.Types.Name
    
    40
    +import GHC.Types.Name.Set
    
    35 41
     import GHC.Types.Basic
    
    36 42
     
    
    37 43
     import GHC.Unit.Module.Imported
    
    ... ... @@ -43,13 +49,12 @@ import GHC.Utils.Fingerprint
    43 49
     import GHC.Utils.Binary
    
    44 50
     import GHC.Utils.Outputable
    
    45 51
     
    
    52
    +import Control.DeepSeq
    
    53
    +import Data.Bifunctor
    
    54
    +import qualified Data.Foldable as Foldable
    
    46 55
     import Data.List (sortBy, sort, partition)
    
    47 56
     import Data.Set (Set)
    
    48 57
     import qualified Data.Set as Set
    
    49
    -import Data.Bifunctor
    
    50
    -import Control.DeepSeq
    
    51
    -import GHC.Types.Name.Set
    
    52
    -
    
    53 58
     
    
    54 59
     
    
    55 60
     -- | Dependency information about ALL modules and packages below this one
    
    ... ... @@ -372,12 +377,12 @@ data Usage
    372 377
             -- we won't spot it here. If you do want to spot that, the caller
    
    373 378
             -- should recursively add them to their useage.
    
    374 379
       }
    
    375
    -  | UsageHomeModuleInterface {
    
    380
    +  | UsageHomeModuleBytecode {
    
    376 381
             usg_mod_name :: ModuleName
    
    377 382
             -- ^ Name of the module
    
    378 383
             , usg_unit_id :: UnitId
    
    379 384
             -- ^ UnitId of the HomeUnit the module is from
    
    380
    -        , usg_iface_hash :: Fingerprint
    
    385
    +        , usg_bytecode_hash :: Fingerprint
    
    381 386
             -- ^ The *interface* hash of the module, not the ABI hash.
    
    382 387
             -- This changes when anything about the interface (and hence the
    
    383 388
             -- module) has changed.
    
    ... ... @@ -412,7 +417,7 @@ instance NFData Usage where
    412 417
       rnf (UsageFile file hash label) = rnf file `seq` rnf hash `seq` rnf label `seq` ()
    
    413 418
       rnf (UsageDirectory dir hash label) = rnf dir `seq` rnf hash `seq` rnf label `seq` ()
    
    414 419
       rnf (UsageMergedRequirement mod hash) = rnf mod `seq` rnf hash `seq` ()
    
    415
    -  rnf (UsageHomeModuleInterface mod uid hash) = rnf mod `seq` rnf uid `seq` rnf hash `seq` ()
    
    420
    +  rnf (UsageHomeModuleBytecode mod uid hash) = rnf mod `seq` rnf uid `seq` rnf hash `seq` ()
    
    416 421
     
    
    417 422
     instance Binary Usage where
    
    418 423
         put_ bh usg@UsagePackageModule{} = do
    
    ... ... @@ -441,11 +446,11 @@ instance Binary Usage where
    441 446
             put_ bh (usg_mod      usg)
    
    442 447
             put_ bh (usg_mod_hash usg)
    
    443 448
     
    
    444
    -    put_ bh usg@UsageHomeModuleInterface{} = do
    
    449
    +    put_ bh usg@UsageHomeModuleBytecode{} = do
    
    445 450
             putByte bh 4
    
    446 451
             put_ bh (usg_mod_name usg)
    
    447 452
             put_ bh (usg_unit_id  usg)
    
    448
    -        put_ bh (usg_iface_hash usg)
    
    453
    +        put_ bh (usg_bytecode_hash usg)
    
    449 454
     
    
    450 455
         put_ bh usg@UsageDirectory{} = do
    
    451 456
             putByte bh 5
    
    ... ... @@ -483,7 +488,7 @@ instance Binary Usage where
    483 488
                 mod <- get bh
    
    484 489
                 uid <- get bh
    
    485 490
                 hash <- get bh
    
    486
    -            return UsageHomeModuleInterface { usg_mod_name = mod, usg_unit_id = uid, usg_iface_hash = hash }
    
    491
    +            return UsageHomeModuleBytecode { usg_mod_name = mod, usg_unit_id = uid, usg_bytecode_hash = hash }
    
    487 492
               5 -> do
    
    488 493
                 dp    <- get bh
    
    489 494
                 hash  <- get bh
    
    ... ... @@ -695,3 +700,33 @@ data ImportAvails
    695 700
               -- ^ Family instance modules below us in the import tree (and maybe
    
    696 701
               -- including us for imported modules)
    
    697 702
           }
    
    703
    +
    
    704
    +-- | Record usage of a 'LinkablePart'.
    
    705
    +data LinkablePartUsage
    
    706
    +  = FileLinkablePartUsage
    
    707
    +    { flu_file :: !FilePath
    
    708
    +    , flu_module :: !Module
    
    709
    +    , flu_linkable_objs :: !(FlatBag OsPath)
    
    710
    +    }
    
    711
    +  | ByteCodeLinkablePartUsage
    
    712
    +    { bclu_module :: !Module
    
    713
    +    , bclu_hash :: !Fingerprint
    
    714
    +    , bclu_linkable_objs :: !(FlatBag OsPath)
    
    715
    +    }
    
    716
    +
    
    717
    +instance Outputable LinkablePartUsage where
    
    718
    +  ppr = \ case
    
    719
    +    FileLinkablePartUsage fp modl _objs ->
    
    720
    +      text "FileLinkableUsage" <+> text fp <+> ppr modl
    
    721
    +
    
    722
    +    ByteCodeLinkablePartUsage modl hash _objs ->
    
    723
    +      text "ByteCodeLinkableUsage" <+> ppr modl <+> ppr hash
    
    724
    +
    
    725
    +linkablePartUsageObjectPaths :: LinkablePartUsage -> [FilePath]
    
    726
    +linkablePartUsageObjectPaths lnkUsage =
    
    727
    +  map OsPath.unsafeDecodeUtf . Foldable.toList $ linkableUsageObjectOsPaths lnkUsage
    
    728
    +
    
    729
    +linkableUsageObjectOsPaths :: LinkablePartUsage -> FlatBag OsPath
    
    730
    +linkableUsageObjectOsPaths lnkUsage = case lnkUsage of
    
    731
    +  FileLinkablePartUsage{flu_linkable_objs} -> flu_linkable_objs
    
    732
    +  ByteCodeLinkablePartUsage{bclu_linkable_objs} -> bclu_linkable_objs

  • compiler/GHC/Unit/Module/Status.hs
    ... ... @@ -18,7 +18,7 @@ import GHC.Unit.Home.ModInfo
    18 18
     import GHC.Unit.Module.ModGuts
    
    19 19
     import GHC.Unit.Module.ModIface
    
    20 20
     
    
    21
    -import GHC.Linker.Types ( Linkable, WholeCoreBindingsLinkable, linkableIsNativeCodeOnly )
    
    21
    +import GHC.Linker.Types ( Linkable, WholeCoreBindingsLinkable, linkableIsNativeCodeOnly, ModuleByteCode, LinkableWith )
    
    22 22
     
    
    23 23
     import GHC.Utils.Fingerprint
    
    24 24
     import GHC.Utils.Outputable
    
    ... ... @@ -59,7 +59,7 @@ data RecompLinkables = RecompLinkables { recompLinkables_bytecode :: !RecompByte
    59 59
                                            , recompLinkables_object   :: !(Maybe Linkable) }
    
    60 60
     
    
    61 61
     data RecompBytecodeLinkable
    
    62
    -  = NormalLinkable !(Maybe Linkable)
    
    62
    +  = NormalLinkable !(Maybe (LinkableWith ModuleByteCode))
    
    63 63
       | WholeCoreBindingsLinkable !WholeCoreBindingsLinkable
    
    64 64
     
    
    65 65
     instance Outputable HscRecompStatus where
    
    ... ... @@ -83,11 +83,9 @@ emptyRecompLinkables = RecompLinkables (NormalLinkable Nothing) Nothing
    83 83
     safeCastHomeModLinkable :: HomeModLinkable -> RecompLinkables
    
    84 84
     safeCastHomeModLinkable (HomeModLinkable bc o) = RecompLinkables (NormalLinkable bc) o
    
    85 85
     
    
    86
    -justBytecode :: Either Linkable WholeCoreBindingsLinkable -> RecompLinkables
    
    86
    +justBytecode :: Either (LinkableWith ModuleByteCode) WholeCoreBindingsLinkable -> RecompLinkables
    
    87 87
     justBytecode = \case
    
    88
    -  Left lm ->
    
    89
    -    assertPpr (not (linkableIsNativeCodeOnly lm)) (ppr lm)
    
    90
    -      $ emptyRecompLinkables { recompLinkables_bytecode = NormalLinkable (Just lm) }
    
    88
    +  Left lm -> emptyRecompLinkables { recompLinkables_bytecode = NormalLinkable (Just lm) }
    
    91 89
       Right lm -> emptyRecompLinkables { recompLinkables_bytecode = WholeCoreBindingsLinkable lm }
    
    92 90
     
    
    93 91
     justObjects :: Linkable -> RecompLinkables
    
    ... ... @@ -95,10 +93,10 @@ justObjects lm =
    95 93
       assertPpr (linkableIsNativeCodeOnly lm) (ppr lm)
    
    96 94
         $ emptyRecompLinkables { recompLinkables_object = Just lm }
    
    97 95
     
    
    98
    -bytecodeAndObjects :: Either Linkable WholeCoreBindingsLinkable -> Linkable -> RecompLinkables
    
    96
    +bytecodeAndObjects :: Either (LinkableWith ModuleByteCode) WholeCoreBindingsLinkable -> Linkable -> RecompLinkables
    
    99 97
     bytecodeAndObjects either_bc o = case either_bc of
    
    100 98
       Left bc ->
    
    101
    -    assertPpr (not (linkableIsNativeCodeOnly bc) && linkableIsNativeCodeOnly o) (ppr bc $$ ppr o)
    
    99
    +    assertPpr (linkableIsNativeCodeOnly o) (ppr o)
    
    102 100
           $ RecompLinkables (NormalLinkable (Just bc)) (Just o)
    
    103 101
       Right bc ->
    
    104 102
         assertPpr (linkableIsNativeCodeOnly o) (ppr o)
    

  • compiler/ghc.cabal.in
    ... ... @@ -215,6 +215,7 @@ Library
    215 215
             GHC.ByteCode.InfoTable
    
    216 216
             GHC.ByteCode.Instr
    
    217 217
             GHC.ByteCode.Linker
    
    218
    +        GHC.ByteCode.Recomp.Binary
    
    218 219
             GHC.ByteCode.Serialize
    
    219 220
             GHC.ByteCode.Types
    
    220 221
             GHC.Cmm
    

  • ghc/GHCi/Leak.hs
    ... ... @@ -52,8 +52,11 @@ getLeakIndicators hsc_env =
    52 52
           return $ LeakModIndicators{..}
    
    53 53
       where
    
    54 54
         mkWeakLinkables :: HomeModLinkable -> IO [Maybe (Weak Linkable)]
    
    55
    -    mkWeakLinkables (HomeModLinkable mbc mo) =
    
    56
    -      mapM (\ln -> traverse (flip mkWeakPtr Nothing <=< evaluate) ln) [mbc, mo]
    
    55
    +    mkWeakLinkables hml =
    
    56
    +      mapM (\ln -> traverse (flip mkWeakPtr Nothing <=< evaluate) ln)
    
    57
    +        [ homeModLinkableByteCode hml
    
    58
    +        , homeModLinkableObject hml
    
    59
    +        ]
    
    57 60
     
    
    58 61
     -- | Look at the LeakIndicators collected by an earlier call to
    
    59 62
     -- `getLeakIndicators`, and print messasges if any of them are still
    

  • testsuite/tests/count-deps/CountDepsAst.stdout
    ... ... @@ -60,6 +60,7 @@ GHC.Data.FastMutInt
    60 60
     GHC.Data.FastString
    
    61 61
     GHC.Data.FastString.Env
    
    62 62
     GHC.Data.FiniteMap
    
    63
    +GHC.Data.FlatBag
    
    63 64
     GHC.Data.Graph.Directed
    
    64 65
     GHC.Data.Graph.Directed.Internal
    
    65 66
     GHC.Data.Graph.UnVar
    

  • testsuite/tests/count-deps/CountDepsParser.stdout
    ... ... @@ -61,6 +61,7 @@ GHC.Data.FastMutInt
    61 61
     GHC.Data.FastString
    
    62 62
     GHC.Data.FastString.Env
    
    63 63
     GHC.Data.FiniteMap
    
    64
    +GHC.Data.FlatBag
    
    64 65
     GHC.Data.Graph.Directed
    
    65 66
     GHC.Data.Graph.Directed.Internal
    
    66 67
     GHC.Data.Graph.Directed.Reachability
    

  • testsuite/tests/driver/multipleHomeUnits/multipleHomeUnits_recomp_th.stdout
    ... ... @@ -3,6 +3,6 @@ GHCi, version 9.15.20260122: https://www.haskell.org/ghc/ :? for help
    3 3
     [2 of 2] Compiling RecompTH         ( RecompTH.hs, interpreted )[recomp]
    
    4 4
     Ok, two modules loaded.
    
    5 5
     ghci> ghci> ghci> [1 of 2] Compiling Dep              ( Dep.hs, interpreted )[dep] [Source file changed]
    
    6
    -[2 of 2] Compiling RecompTH         ( RecompTH.hs, interpreted )[recomp] [Dep changed (interface)]
    
    6
    +[2 of 2] Compiling RecompTH         ( RecompTH.hs, interpreted )[recomp] [Dep changed (bytecode)]
    
    7 7
     Ok, two modules reloaded.
    
    8 8
     ghci> Leaving GHCi.