Matthew Pickering pushed to branch wip/gdc-files at Glasgow Haskell Compiler / GHC

Commits:

6 changed files:

Changes:

  • compiler/GHC/Driver/ByteCode.hs
    1
    +module GHC.Driver.ByteCode where
    
    2
    +
    
    3
    +
    
    4
    +import GHC.Prelude
    
    5
    +
    
    6
    +import GHC.Driver.Session
    
    7
    +import GHC.Driver.CodeOutput
    
    8
    +import GHC.Driver.Env
    
    9
    +import GHC.Runtime.Interpreter
    
    10
    +import GHC.ByteCode.Types
    
    11
    +
    
    12
    +import GHC.Linker.Types
    
    13
    +import GHC.Tc.Utils.Monad
    
    14
    +
    
    15
    +import GHC.Unit
    
    16
    +import GHC.Types.ForeignStubs
    
    17
    +import GHC.Data.Maybe
    
    18
    +
    
    19
    +import Data.List.NonEmpty (NonEmpty ((:|)))
    
    20
    +import {-# SOURCE #-} GHC.Driver.Pipeline
    
    21
    +import Data.Time
    
    22
    +
    
    23
    +import GHC.Platform.Ways
    
    24
    +
    
    25
    +import GHC.ByteCode.Serialize
    
    26
    +
    
    27
    +-- | Write foreign sources and foreign stubs to temporary files and compile them.
    
    28
    +outputAndCompileForeign :: HscEnv -> Module -> ModLocation -> [(ForeignSrcLang, FilePath)] ->  ForeignStubs -> IO [FilePath]
    
    29
    +outputAndCompileForeign hsc_env mod_name location foreign_files foreign_stubs = do
    
    30
    +  let dflags   = hsc_dflags hsc_env
    
    31
    +      logger   = hsc_logger hsc_env
    
    32
    +      tmpfs    = hsc_tmpfs hsc_env
    
    33
    +  (_, has_stub) <- outputForeignStubs logger tmpfs dflags (hsc_units hsc_env) mod_name location foreign_stubs
    
    34
    +  compile_for_interpreter hsc_env $ \ i_env -> do
    
    35
    +    stub_o <- traverse (compileForeign i_env LangC) has_stub
    
    36
    +    foreign_files_o <- traverse (uncurry (compileForeign i_env)) foreign_files
    
    37
    +    pure (maybeToList stub_o ++ foreign_files_o)
    
    38
    +
    
    39
    +-- | Modify flags such that objects are compiled for the interpreter's way.
    
    40
    +-- This is necessary when building foreign objects for Template Haskell, since
    
    41
    +-- those are object code built outside of the pipeline, which means they aren't
    
    42
    +-- subject to the mechanism in 'enableCodeGenWhen' that requests dynamic build
    
    43
    +-- outputs for dependencies when the interpreter used for TH is dynamic but the
    
    44
    +-- main outputs aren't.
    
    45
    +-- Furthermore, the HPT only stores one set of objects with different names for
    
    46
    +-- bytecode linking in 'HomeModLinkable', so the usual hack for switching
    
    47
    +-- between ways in 'get_link_deps' doesn't work.
    
    48
    +compile_for_interpreter :: HscEnv -> (HscEnv -> IO a) -> IO a
    
    49
    +compile_for_interpreter hsc_env use =
    
    50
    +  use (hscUpdateFlags update hsc_env)
    
    51
    +  where
    
    52
    +    update dflags = dflags {
    
    53
    +      targetWays_ = adapt_way interpreterDynamic WayDyn $
    
    54
    +                    adapt_way interpreterProfiled WayProf $
    
    55
    +                    targetWays_ dflags
    
    56
    +      }
    
    57
    +
    
    58
    +    adapt_way want = if want (hscInterp hsc_env) then addWay else removeWay
    
    59
    +
    
    60
    +-- | Write the foreign sources and foreign stubs of a bytecode object to temporary files and compile them.
    
    61
    +loadByteCodeObject :: HscEnv -> ModLocation -> ByteCodeObject
    
    62
    +                             -> IO (CompiledByteCode, [FilePath])
    
    63
    +loadByteCodeObject hsc_env location (ByteCodeObject mod cbc foreign_srcs foreign_stubs) = do
    
    64
    +  fos <- outputAndCompileForeign hsc_env mod location foreign_srcs foreign_stubs
    
    65
    +  return (cbc, fos)
    
    66
    +
    
    67
    +loadByteCodeObjectLinkable :: HscEnv -> UTCTime -> ModLocation -> ByteCodeObject -> IO Linkable
    
    68
    +loadByteCodeObjectLinkable hsc_env linkable_time location bco = do
    
    69
    +  ~(cbc, fos) <- loadByteCodeObject hsc_env location bco
    
    70
    +  return $! Linkable linkable_time (bco_module bco) (BCOs cbc :| [DotO fo ForeignObject | fo <- fos])
    \ No newline at end of file

  • compiler/GHC/Driver/Main.hs
    ... ... @@ -116,6 +116,7 @@ import GHC.Driver.Plugins
    116 116
     import GHC.Driver.Session
    
    117 117
     import GHC.Driver.Backend
    
    118 118
     import GHC.Driver.Env
    
    119
    +import GHC.Driver.ByteCode
    
    119 120
     import GHC.Driver.Env.KnotVars
    
    120 121
     import GHC.Driver.Errors
    
    121 122
     import GHC.Driver.Messager
    
    ... ... @@ -290,12 +291,10 @@ import Data.List.NonEmpty (NonEmpty ((:|)))
    290 291
     import GHC.Unit.Module.WholeCoreBindings
    
    291 292
     import GHC.Types.TypeEnv
    
    292 293
     import System.IO
    
    293
    -import {-# SOURCE #-} GHC.Driver.Pipeline
    
    294 294
     import Data.Time
    
    295 295
     
    
    296 296
     import System.IO.Unsafe ( unsafeInterleaveIO )
    
    297 297
     import GHC.Iface.Env ( trace_if )
    
    298
    -import GHC.Platform.Ways
    
    299 298
     import GHC.Stg.EnforceEpt.TagSig (seqTagSig)
    
    300 299
     import GHC.StgToCmm.Utils (IPEStats)
    
    301 300
     import GHC.Types.Unique.FM
    
    ... ... @@ -884,6 +883,11 @@ hscRecompStatus
    884 883
     
    
    885 884
                    let just_o  = justObjects  <$> obj_linkable
    
    886 885
     
    
    886
    +                   bytecode_or_object_code
    
    887
    +                      | gopt Opt_WriteByteCode lcl_dflags = justBytecode <$> definitely_bc
    
    888
    +                      | otherwise = (justBytecode <$> maybe_bc) `choose` just_o
    
    889
    +
    
    890
    +
    
    887 891
                        definitely_both_os = case (bc_result, obj_linkable) of
    
    888 892
                                    (UpToDateItem bc, UpToDateItem o) -> UpToDateItem (bytecodeAndObjects bc o)
    
    889 893
                                    -- If missing object code, just say we need to recompile because of object code.
    
    ... ... @@ -899,8 +903,7 @@ hscRecompStatus
    899 903
                        -- If not -fwrite-byte-code, then we could use core bindings or object code if that's available.
    
    900 904
                        maybe_bc = bc_in_memory_linkable `choose`
    
    901 905
                                   bc_obj_linkable `choose`
    
    902
    -                              bc_core_linkable `choose`
    
    903
    -                              obj_linkable
    
    906
    +                              bc_core_linkable
    
    904 907
     
    
    905 908
                        bc_result = if gopt Opt_WriteByteCode lcl_dflags
    
    906 909
                                     -- If the byte-code artifact needs to be produced, then we certainly need bytecode.
    
    ... ... @@ -915,8 +918,8 @@ hscRecompStatus
    915 918
     --               pprTraceM "recomp" (ppr just_bc <+> ppr just_o)
    
    916 919
                    -- 2. Decide which of the products we will need
    
    917 920
                    let recomp_linkable_result = case () of
    
    918
    -                     _ | backendCanReuseLoadedCode (backend lcl_dflags) ->
    
    919
    -                           justBytecode <$> bc_result
    
    921
    +                     _ | backendCanReuseLoadedCode (backend lcl_dflags) -> bytecode_or_object_code
    
    922
    +
    
    920 923
                             -- Need object files for making object files
    
    921 924
                             | backendWritesFiles (backend lcl_dflags) ->
    
    922 925
                                if gopt Opt_ByteCodeAndObjectCode lcl_dflags
    
    ... ... @@ -936,13 +939,13 @@ hscRecompStatus
    936 939
     
    
    937 940
     -- | Prefer requires both arguments to be up-to-date.
    
    938 941
     -- but prefers to use the second argument.
    
    939
    -prefer :: MaybeValidated Linkable -> MaybeValidated Linkable -> MaybeValidated Linkable
    
    942
    +prefer :: MaybeValidated a -> MaybeValidated a -> MaybeValidated a
    
    940 943
     prefer (UpToDateItem _) (UpToDateItem l2) = UpToDateItem l2
    
    941 944
     prefer r1 _ = r1
    
    942 945
     
    
    943 946
     -- | Disjunction, choose either argument, but prefer the first one.
    
    944 947
     -- Report the failure of the first argument.
    
    945
    -choose :: MaybeValidated Linkable -> MaybeValidated Linkable -> MaybeValidated Linkable
    
    948
    +choose :: MaybeValidated a -> MaybeValidated a -> MaybeValidated a
    
    946 949
     choose (UpToDateItem l1) _ = UpToDateItem l1
    
    947 950
     choose _ (UpToDateItem l2) = UpToDateItem l2
    
    948 951
     choose l1 _ = l1
    
    ... ... @@ -1052,26 +1055,6 @@ initModDetails hsc_env iface =
    1052 1055
         -- in make mode, since this HMI will go into the HPT.
    
    1053 1056
         genModDetails hsc_env iface
    
    1054 1057
     
    
    1055
    --- | Modify flags such that objects are compiled for the interpreter's way.
    
    1056
    --- This is necessary when building foreign objects for Template Haskell, since
    
    1057
    --- those are object code built outside of the pipeline, which means they aren't
    
    1058
    --- subject to the mechanism in 'enableCodeGenWhen' that requests dynamic build
    
    1059
    --- outputs for dependencies when the interpreter used for TH is dynamic but the
    
    1060
    --- main outputs aren't.
    
    1061
    --- Furthermore, the HPT only stores one set of objects with different names for
    
    1062
    --- bytecode linking in 'HomeModLinkable', so the usual hack for switching
    
    1063
    --- between ways in 'get_link_deps' doesn't work.
    
    1064
    -compile_for_interpreter :: HscEnv -> (HscEnv -> IO a) -> IO a
    
    1065
    -compile_for_interpreter hsc_env use =
    
    1066
    -  use (hscUpdateFlags update hsc_env)
    
    1067
    -  where
    
    1068
    -    update dflags = dflags {
    
    1069
    -      targetWays_ = adapt_way interpreterDynamic WayDyn $
    
    1070
    -                    adapt_way interpreterProfiled WayProf $
    
    1071
    -                    targetWays_ dflags
    
    1072
    -      }
    
    1073
    -
    
    1074
    -    adapt_way want = if want (hscInterp hsc_env) then addWay else removeWay
    
    1075 1058
     
    
    1076 1059
     -- | Assemble 'WholeCoreBindings' if the interface contains Core bindings.
    
    1077 1060
     iface_core_bindings :: ModIface -> ModLocation -> Maybe WholeCoreBindings
    
    ... ... @@ -2257,30 +2240,6 @@ generateAndWriteByteCodeLinkable hsc_env cgguts mod_location = do
    2257 2240
       bco_time <- maybe getCurrentTime pure =<< modificationTimeIfExists (ml_bytecode_file mod_location)
    
    2258 2241
       loadByteCodeObjectLinkable hsc_env bco_time mod_location bco_object
    
    2259 2242
     
    
    2260
    --- | Write foreign sources and foreign stubs to temporary files and compile them.
    
    2261
    -outputAndCompileForeign :: HscEnv -> Module -> ModLocation -> [(ForeignSrcLang, FilePath)] ->  ForeignStubs -> IO [FilePath]
    
    2262
    -outputAndCompileForeign hsc_env mod_name location foreign_files foreign_stubs = do
    
    2263
    -  let dflags   = hsc_dflags hsc_env
    
    2264
    -      logger   = hsc_logger hsc_env
    
    2265
    -      tmpfs    = hsc_tmpfs hsc_env
    
    2266
    -  (_, has_stub) <- outputForeignStubs logger tmpfs dflags (hsc_units hsc_env) mod_name location foreign_stubs
    
    2267
    -  compile_for_interpreter hsc_env $ \ i_env -> do
    
    2268
    -    stub_o <- traverse (compileForeign i_env LangC) has_stub
    
    2269
    -    foreign_files_o <- traverse (uncurry (compileForeign i_env)) foreign_files
    
    2270
    -    pure (maybeToList stub_o ++ foreign_files_o)
    
    2271
    -
    
    2272
    --- | Write the foreign sources and foreign stubs of a bytecode object to temporary files and compile them.
    
    2273
    -loadByteCodeObject :: HscEnv -> ModLocation -> ByteCodeObject
    
    2274
    -                             -> IO (CompiledByteCode, [FilePath])
    
    2275
    -loadByteCodeObject hsc_env location (ByteCodeObject mod cbc foreign_srcs foreign_stubs) = do
    
    2276
    -  fos <- outputAndCompileForeign hsc_env mod location foreign_srcs foreign_stubs
    
    2277
    -  return (cbc, fos)
    
    2278
    -
    
    2279
    -loadByteCodeObjectLinkable :: HscEnv -> UTCTime -> ModLocation -> ByteCodeObject -> IO Linkable
    
    2280
    -loadByteCodeObjectLinkable hsc_env linkable_time location bco = do
    
    2281
    -  (cbc, fos) <- loadByteCodeObject hsc_env location bco
    
    2282
    -  return $! Linkable linkable_time (bco_module bco) (BCOs cbc :| [DotO fo ForeignObject | fo <- fos])
    
    2283
    -
    
    2284 2243
     mkByteCodeObject :: HscEnv -> Module -> ModLocation -> CgInteractiveGuts -> IO ByteCodeObject
    
    2285 2244
     mkByteCodeObject hsc_env mod mod_location cgguts = do
    
    2286 2245
       bcos <- hscGenerateByteCode hsc_env cgguts mod_location
    

  • compiler/GHC/HsToCore/Usage.hs
    ... ... @@ -187,7 +187,9 @@ mkObjectUsage pit plugins fc hug th_links_needed th_pkgs_needed = do
    187 187
               -- home package ifaces in the PIT.
    
    188 188
               miface <- lookupIfaceByModule hug pit m
    
    189 189
               case miface of
    
    190
    -            Nothing -> pprPanic "mkObjectUsage" (ppr m)
    
    190
    +            -- TODO: MP: This is wrong, a placeholder for now.
    
    191
    +            -- We need to work out what to do for bytecode linkables which are not loaded into HPT
    
    192
    +            Nothing -> return $ UsageHomeModuleInterface (moduleName m) (toUnitId $ moduleUnit m) fingerprint0
    
    191 193
                 Just iface ->
    
    192 194
                   return $ UsageHomeModuleInterface (moduleName m) (toUnitId $ moduleUnit m) (mi_iface_hash iface)
    
    193 195
     
    

  • compiler/GHC/Linker/Deps.hs
    ... ... @@ -59,7 +59,7 @@ data LinkDepsOpts = LinkDepsOpts
    59 59
       , ldWays        :: !Ways                          -- ^ Enabled ways
    
    60 60
       , ldFinderCache :: !FinderCache
    
    61 61
       , ldFinderOpts  :: !FinderOpts
    
    62
    -  , ldLoadByteCode :: !(Module -> IO (Maybe Linkable))
    
    62
    +  , ldLoadByteCode :: !(Module -> ModLocation -> IO (Maybe Linkable))
    
    63 63
       , ldGetDependencies :: !([Module] -> IO ([Module], UniqDSet UnitId))
    
    64 64
       }
    
    65 65
     
    
    ... ... @@ -161,8 +161,15 @@ get_link_deps opts pls maybe_normal_osuf span mods = do
    161 161
                case ue_homeUnit unit_env of
    
    162 162
                 Nothing -> no_obj mod
    
    163 163
                 Just home_unit -> do
    
    164
    -              from_bc <- ldLoadByteCode opts mod
    
    165
    -              maybe (fallback_no_bytecode home_unit mod) pure from_bc
    
    164
    +
    
    165
    +              let fc = ldFinderCache opts
    
    166
    +              let fopts = ldFinderOpts opts
    
    167
    +              mb_stuff <- findHomeModule fc fopts home_unit (moduleName mod)
    
    168
    +              case mb_stuff of
    
    169
    +                Found loc _ -> do
    
    170
    +                  from_bc <- ldLoadByteCode opts mod loc
    
    171
    +                  maybe (fallback_no_bytecode home_unit mod) pure from_bc
    
    172
    +                _ -> fallback_no_bytecode home_unit mod
    
    166 173
             where
    
    167 174
     
    
    168 175
                 fallback_no_bytecode home_unit mod = do
    

  • compiler/GHC/Linker/Loader.hs
    ... ... @@ -39,6 +39,7 @@ where
    39 39
     import GHC.Prelude
    
    40 40
     
    
    41 41
     import GHC.Settings
    
    42
    +import GHC.Utils.Misc
    
    42 43
     
    
    43 44
     import GHC.Platform
    
    44 45
     import GHC.Platform.Ways
    
    ... ... @@ -48,6 +49,7 @@ import GHC.Driver.Phases
    48 49
     import GHC.Driver.Env
    
    49 50
     import GHC.Driver.Session
    
    50 51
     import GHC.Driver.Ppr
    
    52
    +import GHC.Driver.ByteCode
    
    51 53
     import GHC.Driver.Config.Diagnostic
    
    52 54
     import GHC.Driver.Config.Finder
    
    53 55
     
    
    ... ... @@ -129,6 +131,7 @@ import qualified GHC.Runtime.Interpreter as GHCi
    129 131
     import qualified Data.IntMap.Strict as IM
    
    130 132
     import qualified Data.Map.Strict as M
    
    131 133
     import Foreign.Ptr (nullPtr)
    
    134
    +import GHC.ByteCode.Serialize
    
    132 135
     
    
    133 136
     -- Note [Linkers and loaders]
    
    134 137
     -- ~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -628,7 +631,14 @@ initLinkDepsOpts hsc_env = opts
    628 631
                 }
    
    629 632
         dflags = hsc_dflags hsc_env
    
    630 633
     
    
    631
    -    ldLoadByteCode mod = do
    
    634
    +    ldLoadByteCode mod locn = do
    
    635
    +      bco <-  findBytecodeLinkableMaybe hsc_env mod locn
    
    636
    +      case bco of
    
    637
    +        Nothing -> findWholeCoreBindings hsc_env mod
    
    638
    +        Just bco -> return (Just bco)
    
    639
    +
    
    640
    +findWholeCoreBindings :: HscEnv -> Module -> IO (Maybe Linkable)
    
    641
    +findWholeCoreBindings hsc_env mod = do
    
    632 642
           _ <- initIfaceLoad hsc_env $
    
    633 643
                  loadInterface (text "get_reachable_nodes" <+> parens (ppr mod))
    
    634 644
                      mod ImportBySystem
    
    ... ... @@ -636,6 +646,16 @@ initLinkDepsOpts hsc_env = opts
    636 646
           sequence (lookupModuleEnv eps_iface_bytecode mod)
    
    637 647
     
    
    638 648
     
    
    649
    +findBytecodeLinkableMaybe :: HscEnv -> Module -> ModLocation -> IO (Maybe Linkable)
    
    650
    +findBytecodeLinkableMaybe hsc_env _mod locn = do
    
    651
    +  let bytecode_fn = ml_bytecode_file locn
    
    652
    +  maybe_bytecode_time <- modificationTimeIfExists bytecode_fn
    
    653
    +  case maybe_bytecode_time of
    
    654
    +    Nothing -> return Nothing
    
    655
    +    Just bytecode_time -> do
    
    656
    +      bco <- readBinByteCode hsc_env bytecode_fn
    
    657
    +      Just <$> loadByteCodeObjectLinkable hsc_env bytecode_time locn bco
    
    658
    +
    
    639 659
     get_reachable_nodes :: HscEnv -> [Module] -> IO ([Module], UniqDSet UnitId)
    
    640 660
     get_reachable_nodes hsc_env mods
    
    641 661
     
    

  • compiler/ghc.cabal.in
    ... ... @@ -490,6 +490,7 @@ Library
    490 490
             GHC.Driver.Backend.Internal
    
    491 491
             GHC.Driver.Backpack
    
    492 492
             GHC.Driver.Backpack.Syntax
    
    493
    +        GHC.Driver.ByteCode
    
    493 494
             GHC.Driver.CmdLine
    
    494 495
             GHC.Driver.CodeOutput
    
    495 496
             GHC.Driver.Config