Torsten Schmits pushed to branch wip/torsten.schmits/mercury-ghc910-mhu-transitive-th-deps at Glasgow Haskell Compiler / GHC

Commits:

3 changed files:

Changes:

  • compiler/GHC/Linker/Deps.hs
    ... ... @@ -11,6 +11,7 @@
    11 11
     module GHC.Linker.Deps
    
    12 12
       ( LinkDepsOpts (..)
    
    13 13
       , LinkDeps (..)
    
    14
    +  , LibraryUnits (..)
    
    14 15
       , getLinkDeps
    
    15 16
       )
    
    16 17
     where
    
    ... ... @@ -83,10 +84,16 @@ data LinkDepsOpts = LinkDepsOpts
    83 84
     data LinkDeps = LinkDeps
    
    84 85
       { ldNeededLinkables :: [Linkable]
    
    85 86
       , ldAllLinkables    :: [Linkable]
    
    86
    -  , ldNeededUnits     :: [UnitId]
    
    87
    +  , ldNeededUnits     :: [LibraryUnits]
    
    87 88
       , ldAllUnits        :: UniqDSet UnitId
    
    88 89
       }
    
    89 90
     
    
    91
    +data LibraryUnits
    
    92
    +  = LibraryUnits
    
    93
    +  { home_unit :: !UnitId
    
    94
    +  , library_unit :: !UnitId
    
    95
    +  }
    
    96
    +
    
    90 97
     -- | Find all the packages and linkables that a set of modules depends on
    
    91 98
     --
    
    92 99
     -- Return the module and package dependencies for the needed modules.
    
    ... ... @@ -155,10 +162,10 @@ get_link_deps opts pls maybe_normal_osuf span mods = do
    155 162
             link_mods =
    
    156 163
               listToUDFM [(moduleName (mi_module (hm_iface m)), m) | m <- mmods]
    
    157 164
             link_libs =
    
    158
    -          uniqDSetToList (unionManyUniqDSets (init_pkg_set : pkgs))
    
    165
    +          eltsUDFM (foldl' plusUDFM emptyUDFM (init_pkg_set : pkgs))
    
    159 166
           pure $
    
    160 167
             LinkModules (LinkHomeModule <$> link_mods) :
    
    161
    -        (LinkLibrary <$> link_libs)
    
    168
    +        link_libs
    
    162 169
     
    
    163 170
         -- This code is used in `--make` mode to calculate the home package and unit dependencies
    
    164 171
         -- for a set of modules.
    
    ... ... @@ -168,7 +175,7 @@ get_link_deps opts pls maybe_normal_osuf span mods = do
    168 175
     
    
    169 176
         -- It is also a matter of correctness to use the module graph so that dependencies between home units
    
    170 177
         -- is resolved correctly.
    
    171
    -    make_deps_loop :: (UniqDSet UnitId, Set.Set NodeKey) -> [ModNodeKeyWithUid] -> (UniqDSet UnitId, Set.Set NodeKey)
    
    178
    +    make_deps_loop :: (UniqDFM UnitId LinkDep, Set.Set NodeKey) -> [ModNodeKeyWithUid] -> (UniqDFM UnitId LinkDep, Set.Set NodeKey)
    
    172 179
         make_deps_loop found [] = found
    
    173 180
         make_deps_loop found@(found_units, found_mods) (nk:nexts)
    
    174 181
           | NodeKey_Module nk `Set.member` found_mods = make_deps_loop found nexts
    
    ... ... @@ -176,7 +183,7 @@ get_link_deps opts pls maybe_normal_osuf span mods = do
    176 183
             case fmap mkNodeKey <$> mgReachable mod_graph (NodeKey_Module nk) of
    
    177 184
               Nothing ->
    
    178 185
                   let (ModNodeKeyWithUid _ uid) = nk
    
    179
    -              in make_deps_loop (addOneToUniqDSet found_units uid, found_mods) nexts
    
    186
    +              in make_deps_loop (addToUDFM found_units uid (LinkLibrary LibraryUnits {library_unit = uid, home_unit = (ue_current_unit (ldUnitEnv opts))}), found_mods) nexts
    
    180 187
               Just trans_deps ->
    
    181 188
                 let deps = Set.insert (NodeKey_Module nk) (Set.fromList trans_deps)
    
    182 189
                     -- See #936 and the ghci.prog007 test for why we have to continue traversing through
    
    ... ... @@ -185,7 +192,7 @@ get_link_deps opts pls maybe_normal_osuf span mods = do
    185 192
                 in make_deps_loop (found_units, deps `Set.union` found_mods) (todo_boot_mods ++ nexts)
    
    186 193
     
    
    187 194
         mkNk m = ModNodeKeyWithUid (GWIB (moduleName m) NotBoot) (moduleUnitId m)
    
    188
    -    (init_pkg_set, all_deps) = make_deps_loop (emptyUniqDSet, Set.empty) $ map mkNk (filterOut isInteractiveModule mods)
    
    195
    +    (init_pkg_set, all_deps) = make_deps_loop (emptyUDFM, Set.empty) $ map mkNk (filterOut isInteractiveModule mods)
    
    189 196
     
    
    190 197
         all_home_mods = [with_uid | NodeKey_Module with_uid <- Set.toList all_deps]
    
    191 198
     
    
    ... ... @@ -195,7 +202,7 @@ get_link_deps opts pls maybe_normal_osuf span mods = do
    195 202
               let iface = hm_iface hmi
    
    196 203
               case mi_hsc_src iface of
    
    197 204
                 HsBootFile -> throwProgramError opts $ link_boot_mod_error (mi_module iface)
    
    198
    -            _ -> pure (mkUniqDSet $ Set.toList $ dep_direct_pkgs (mi_deps iface), hmi)
    
    205
    +            _ -> pure (listToUDFM [(u, LinkLibrary LibraryUnits {library_unit = u, home_unit = (moduleUnitId (mi_module iface))}) | u <- Set.toList $ dep_direct_pkgs (mi_deps iface)], hmi)
    
    199 206
             Nothing -> throwProgramError opts $
    
    200 207
               text "getLinkDeps: Home module not loaded" <+> ppr (gwib_mod gwib) <+> ppr uid
    
    201 208
     
    
    ... ... @@ -279,12 +286,13 @@ instance Outputable LinkModule where
    279 286
     data LinkDep =
    
    280 287
       LinkModules (UniqDFM ModuleName LinkModule)
    
    281 288
       |
    
    282
    -  LinkLibrary UnitId
    
    289
    +  LinkLibrary LibraryUnits
    
    283 290
     
    
    284 291
     instance Outputable LinkDep where
    
    285 292
       ppr = \case
    
    286 293
         LinkModules mods -> text "modules:" <+> ppr (eltsUDFM mods)
    
    287
    -    LinkLibrary uid -> text "library:" <+> ppr uid
    
    294
    +    LinkLibrary (LibraryUnits {home_unit, library_unit}) ->
    
    295
    +      text "library:" <+> ppr library_unit <+> parens (ppr home_unit)
    
    288 296
     
    
    289 297
     data OneshotError =
    
    290 298
       NoLocation Module
    
    ... ... @@ -337,7 +345,7 @@ oneshot_deps_loop opts (mod : mods) acc = do
    337 345
         already_seen
    
    338 346
           | Just (LinkModules mods) <- mod_dep
    
    339 347
           = elemUDFM mod_name mods
    
    340
    -      | Just (LinkLibrary _) <- mod_dep
    
    348
    +      | Just (LinkLibrary {}) <- mod_dep
    
    341 349
           = True
    
    342 350
           | otherwise
    
    343 351
           = False
    
    ... ... @@ -362,7 +370,7 @@ oneshot_deps_loop opts (mod : mods) acc = do
    362 370
           | otherwise
    
    363 371
           = add_library
    
    364 372
     
    
    365
    -    add_library = pure (addToUDFM acc mod_unit_id (LinkLibrary mod_unit_id), [])
    
    373
    +    add_library = pure (addToUDFM acc mod_unit_id (LinkLibrary LibraryUnits {library_unit = mod_unit_id, home_unit}), [])
    
    366 374
     
    
    367 375
         add_module iface lmod =
    
    368 376
           (addListToUDFM with_mod (direct_pkgs iface), new_deps iface)
    
    ... ... @@ -378,7 +386,7 @@ oneshot_deps_loop opts (mod : mods) acc = do
    378 386
           | bytecode
    
    379 387
           = []
    
    380 388
           | otherwise
    
    381
    -      = [(u, LinkLibrary u) | u <- Set.toList (dep_direct_pkgs (mi_deps iface))]
    
    389
    +      = [(u, LinkLibrary LibraryUnits {library_unit = u, home_unit}) | u <- Set.toList (dep_direct_pkgs (mi_deps iface))]
    
    382 390
     
    
    383 391
         new_deps iface
    
    384 392
           | bytecode
    
    ... ... @@ -418,6 +426,7 @@ oneshot_deps_loop opts (mod : mods) acc = do
    418 426
           text "due to use of Template Haskell"
    
    419 427
     
    
    420 428
         bytecode = ldUseByteCode opts
    
    429
    +    home_unit = homeUnitId (expectJust "oneshot_deps" mb_home)
    
    421 430
         mb_home = ue_homeUnit (ldUnitEnv opts)
    
    422 431
     
    
    423 432
     link_boot_mod_error :: Module -> SDoc
    
    ... ... @@ -428,7 +437,7 @@ link_boot_mod_error mod =
    428 437
     classify_deps ::
    
    429 438
       LoaderState ->
    
    430 439
       [LinkDep] ->
    
    431
    -  ([Linkable], [LinkModule], UniqDSet UnitId, [UnitId])
    
    440
    +  ([Linkable], [LinkModule], UniqDSet UnitId, [LibraryUnits])
    
    432 441
     classify_deps pls deps =
    
    433 442
       (loaded_modules, needed_modules, all_packages, needed_packages)
    
    434 443
       where
    
    ... ... @@ -436,13 +445,15 @@ classify_deps pls deps =
    436 445
           partitionWith loaded_or_needed (concatMap eltsUDFM modules)
    
    437 446
     
    
    438 447
         needed_packages =
    
    439
    -      eltsUDFM (getUniqDSet all_packages `minusUDFM` pkgs_loaded pls)
    
    448
    +      eltsUDFM (packages `minusUDFM` pkgs_loaded pls)
    
    449
    +
    
    450
    +    packages = listToUDFM [(library_unit p, p) | p <- packages_with_home_units]
    
    440 451
     
    
    441
    -    all_packages = mkUniqDSet packages
    
    452
    +    all_packages = mkUniqDSet (map library_unit packages_with_home_units)
    
    442 453
     
    
    443
    -    (modules, packages) = flip partitionWith deps $ \case
    
    454
    +    (modules, packages_with_home_units) = flip partitionWith deps $ \case
    
    444 455
           LinkModules mods -> Left mods
    
    445
    -      LinkLibrary lib -> Right lib
    
    456
    +      LinkLibrary units -> Right units
    
    446 457
     
    
    447 458
         loaded_or_needed lm =
    
    448 459
           maybe (Right lm) Left (loaded_linkable (mi_module (link_module_iface lm)))
    

  • compiler/GHC/Linker/Loader.hs
    ... ... @@ -93,8 +93,9 @@ import Control.Monad
    93 93
     
    
    94 94
     import qualified Data.Set as Set
    
    95 95
     import Data.Char (isSpace)
    
    96
    +import Data.Foldable (for_)
    
    96 97
     import Data.IORef
    
    97
    -import Data.List (intercalate, isPrefixOf, nub, partition)
    
    98
    +import Data.List (intercalate, isPrefixOf, nub, partition, sortOn)
    
    98 99
     import Data.Maybe
    
    99 100
     import Control.Concurrent.MVar
    
    100 101
     import qualified Control.Monad.Catch as MC
    
    ... ... @@ -109,6 +110,7 @@ import System.Win32.Info (getSystemDirectory)
    109 110
     #endif
    
    110 111
     
    
    111 112
     import GHC.Utils.Exception
    
    113
    +import qualified Data.List.NonEmpty as NE
    
    112 114
     
    
    113 115
     -- Note [Linkers and loaders]
    
    114 116
     -- ~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -173,7 +175,7 @@ emptyLoaderState = LoaderState
    173 175
       --
    
    174 176
       -- The linker's symbol table is populated with RTS symbols using an
    
    175 177
       -- explicit list.  See rts/Linker.c for details.
    
    176
    -  where init_pkgs = unitUDFM rtsUnitId (LoadedPkgInfo rtsUnitId [] [] [] emptyUniqDSet)
    
    178
    +  where init_pkgs = unitUDFM rtsUnitId (LoadedPkgInfo rtsUnitId Nothing [] [] [] emptyUniqDSet)
    
    177 179
     
    
    178 180
     extendLoadedEnv :: Interp -> [(Name,ForeignHValue)] -> IO ()
    
    179 181
     extendLoadedEnv interp new_bindings =
    
    ... ... @@ -325,9 +327,8 @@ reallyInitLoaderState interp hsc_env = do
    325 327
           -- (a) initialise the C dynamic linker
    
    326 328
           initObjLinker interp
    
    327 329
     
    
    328
    -
    
    329 330
           -- (b) Load packages from the command-line (Note [preload packages])
    
    330
    -      pls <- unitEnv_foldWithKey (\k u env -> k >>= \pls' -> loadPackages' interp (hscSetActiveUnitId u hsc_env) (preloadUnits (homeUnitEnv_units env)) pls') (return pls0) (hsc_HUG hsc_env)
    
    331
    +      pls <- unitEnv_foldWithKey (\k u env -> k >>= \pls' -> loadPackages' interp hsc_env [LibraryUnits {home_unit = u, library_unit = pre} | pre <- preloadUnits (homeUnitEnv_units env)] pls') (return pls0) (hsc_HUG hsc_env)
    
    331 332
     
    
    332 333
           -- steps (c), (d) and (e)
    
    333 334
           loadCmdLineLibs' interp hsc_env pls
    
    ... ... @@ -855,7 +856,13 @@ dynLoadObjs interp hsc_env pls@LoaderState{..} objs = do
    855 856
         -- link all "loaded packages" so symbols in those can be resolved
    
    856 857
         -- Note: We are loading packages with local scope, so to see the
    
    857 858
         -- symbols in this link we must link all loaded packages again.
    
    858
    -    linkDynLib logger tmpfs dflags2 unit_env objs (loaded_pkg_uid <$> eltsUDFM pkgs_loaded)
    
    859
    +    do
    
    860
    +      let groupedLoadedPackageInfos = groupLoadedPackageInfosByParent pkgs_loaded
    
    861
    +      for_ groupedLoadedPackageInfos $ \(mParent, loaded_pkg_uids) -> do
    
    862
    +        let unit_env' = case mParent of
    
    863
    +              Nothing -> unit_env
    
    864
    +              Just parent -> ue_setActiveUnit parent unit_env
    
    865
    +        linkDynLib logger tmpfs dflags2 unit_env' objs loaded_pkg_uids
    
    859 866
     
    
    860 867
         -- if we got this far, extend the lifetime of the library file
    
    861 868
         changeTempFilesLifetime tmpfs TFL_GhcSession [soFile]
    
    ... ... @@ -866,6 +873,19 @@ dynLoadObjs interp hsc_env pls@LoaderState{..} objs = do
    866 873
       where
    
    867 874
         msg = "GHC.Linker.Loader.dynLoadObjs: Loading temp shared object failed"
    
    868 875
     
    
    876
    +    groupOn :: Eq k => (a -> k) -> [a] -> [NE.NonEmpty a]
    
    877
    +    groupOn f = NE.groupBy ((==) `on2` f)
    
    878
    +        -- redefine on so we avoid duplicate computation for most values.
    
    879
    +        where (.*.) `on2` f = \x -> let fx = f x in \y -> fx .*. f y
    
    880
    +
    
    881
    +    groupLoadedPackageInfosByParent :: PkgsLoaded -> [(Maybe UnitId, [UnitId])]
    
    882
    +    groupLoadedPackageInfosByParent pkgs =
    
    883
    +      map (\l -> (loaded_pkg_parent (NE.head l), NE.toList $ NE.map loaded_pkg_uid l))
    
    884
    +        $ groupOn loaded_pkg_parent
    
    885
    +        $ sortOn loaded_pkg_parent
    
    886
    +        $ eltsUDFM pkgs
    
    887
    +
    
    888
    +
    
    869 889
     rmDupLinkables :: LinkableSet    -- Already loaded
    
    870 890
                    -> [Linkable]    -- New linkables
    
    871 891
                    -> (LinkableSet,  -- New loaded set (including new ones)
    
    ... ... @@ -1075,36 +1095,39 @@ loadPackages interp hsc_env new_pkgs = do
    1075 1095
       -- a lock.
    
    1076 1096
       initLoaderState interp hsc_env
    
    1077 1097
       modifyLoaderState_ interp $ \pls ->
    
    1078
    -    loadPackages' interp hsc_env new_pkgs pls
    
    1098
    +    loadPackages' interp hsc_env [LibraryUnits {home_unit = hscActiveUnitId hsc_env, library_unit} | library_unit <- new_pkgs] pls
    
    1079 1099
     
    
    1080
    -loadPackages' :: Interp -> HscEnv -> [UnitId] -> LoaderState -> IO LoaderState
    
    1081
    -loadPackages' interp hsc_env new_pks pls = do
    
    1100
    +loadPackages' :: Interp -> HscEnv -> [LibraryUnits] -> LoaderState -> IO LoaderState
    
    1101
    +loadPackages' interp hsc_env0 new_pks pls = do
    
    1082 1102
         pkgs' <- link (pkgs_loaded pls) new_pks
    
    1083 1103
         return $! pls { pkgs_loaded = pkgs'
    
    1084 1104
                       }
    
    1085 1105
       where
    
    1086
    -     link :: PkgsLoaded -> [UnitId] -> IO PkgsLoaded
    
    1106
    +     link :: PkgsLoaded -> [LibraryUnits] -> IO PkgsLoaded
    
    1087 1107
          link pkgs new_pkgs =
    
    1088 1108
              foldM link_one pkgs new_pkgs
    
    1089 1109
     
    
    1090
    -     link_one pkgs new_pkg
    
    1091
    -        | new_pkg `elemUDFM` pkgs   -- Already linked
    
    1110
    +     link_one pkgs (LibraryUnits {home_unit, library_unit})
    
    1111
    +        | library_unit `elemUDFM` pkgs   -- Already linked
    
    1092 1112
             = return pkgs
    
    1093 1113
     
    
    1094
    -        | Just pkg_cfg <- lookupUnitId (hsc_units hsc_env) new_pkg
    
    1114
    +        | Just pkg_cfg <- lookupUnitId (hsc_units (hscSetActiveUnitId home_unit hsc_env)) library_unit
    
    1095 1115
             = do { let deps = unitDepends pkg_cfg
    
    1096 1116
                    -- Link dependents first
    
    1097
    -             ; pkgs' <- link pkgs deps
    
    1117
    +             ; pkgs' <- link pkgs [LibraryUnits {home_unit, library_unit} | library_unit <- deps]
    
    1118
    +
    
    1098 1119
                     -- Now link the package itself
    
    1099 1120
                  ; (hs_cls, extra_cls, loaded_dlls) <- loadPackage interp hsc_env pkg_cfg
    
    1100 1121
                  ; let trans_deps = unionManyUniqDSets [ addOneToUniqDSet (loaded_pkg_trans_deps loaded_pkg_info) dep_pkg
    
    1101 1122
                                                        | dep_pkg <- deps
    
    1102 1123
                                                        , Just loaded_pkg_info <- pure (lookupUDFM pkgs' dep_pkg)
    
    1103 1124
                                                        ]
    
    1104
    -             ; return (addToUDFM pkgs' new_pkg (LoadedPkgInfo new_pkg hs_cls extra_cls loaded_dlls trans_deps)) }
    
    1125
    +             ; return (addToUDFM pkgs' library_unit (LoadedPkgInfo library_unit (Just home_unit) hs_cls extra_cls loaded_dlls trans_deps)) }
    
    1105 1126
     
    
    1106 1127
             | otherwise
    
    1107
    -        = throwGhcExceptionIO (CmdLineError ("unknown package: " ++ unpackFS (unitIdFS new_pkg)))
    
    1128
    +        = throwGhcExceptionIO (CmdLineError ("unknown package: " ++ unpackFS (unitIdFS library_unit)))
    
    1129
    +        where
    
    1130
    +          hsc_env = hscSetActiveUnitId home_unit hsc_env0
    
    1108 1131
     
    
    1109 1132
     
    
    1110 1133
     loadPackage :: Interp -> HscEnv -> UnitInfo -> IO ([LibrarySpec], [LibrarySpec], [RemotePtr LoadedDLL])
    

  • compiler/GHC/Linker/Types.hs
    ... ... @@ -192,6 +192,7 @@ type PkgsLoaded = UniqDFM UnitId LoadedPkgInfo
    192 192
     data LoadedPkgInfo
    
    193 193
       = LoadedPkgInfo
    
    194 194
       { loaded_pkg_uid         :: !UnitId
    
    195
    +  , loaded_pkg_parent      :: !(Maybe UnitId)
    
    195 196
       , loaded_pkg_hs_objs     :: ![LibrarySpec]
    
    196 197
       , loaded_pkg_non_hs_objs :: ![LibrarySpec]
    
    197 198
       , loaded_pkg_hs_dlls     :: ![RemotePtr LoadedDLL]
    
    ... ... @@ -200,8 +201,9 @@ data LoadedPkgInfo
    200 201
       }
    
    201 202
     
    
    202 203
     instance Outputable LoadedPkgInfo where
    
    203
    -  ppr (LoadedPkgInfo uid hs_objs non_hs_objs _ trans_deps) =
    
    204
    -    vcat [ppr uid
    
    204
    +  ppr (LoadedPkgInfo uid parent_uid hs_objs non_hs_objs _ trans_deps) =
    
    205
    +    vcat [ ppr uid
    
    206
    +         , ppr parent_uid
    
    205 207
              , ppr hs_objs
    
    206 208
              , ppr non_hs_objs
    
    207 209
              , ppr trans_deps ]