Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC

Commits:

5 changed files:

Changes:

  • changelog.d/deterministic-usage-order
    1
    +section: compiler
    
    2
    +synopsis: Make the order of usages deterministic
    
    3
    +issues: #26877
    
    4
    +mrs: !15484
    
    5
    +description: {
    
    6
    +    The order in which usages appear in interface files is now
    
    7
    +    deterministic.
    
    8
    +}

  • changelog.d/module-graph-reuse-in-downsweep
    ... ... @@ -3,7 +3,7 @@ synopsis: Allow `downsweep` to use nodes of an existing module graph
    3 3
     issues: #27054
    
    4 4
     mrs: !16028
    
    5 5
     description: {
    
    6
    -    This contribution enables `downsweep` to use the nodes of a module
    
    7
    -    graph obtained from a previous downsweeping round, which allows GHC
    
    8
    -    API applications to build module graphs somewhat incrementally.
    
    6
    +    The `downsweep` operation can now use the nodes of a module graph
    
    7
    +    obtained from a previous downsweeping round, which allows GHC API
    
    8
    +    applications to build module graphs somewhat incrementally.
    
    9 9
     }

  • changelog.d/more-efficient-home-unit-imports-finding
    ... ... @@ -3,13 +3,10 @@ synopsis: Introduce a cache of home module name providers
    3 3
     issues: #27055
    
    4 4
     mrs: !15888
    
    5 5
     description: {
    
    6
    -    This contribution optimizes the algorithm for finding out which home
    
    7
    -    unit provides the module that a certain import declaration refers
    
    8
    -    to. The previous approach has been to simply search all home units
    
    9
    -    in no particular order. This change introduces a cache that allows
    
    10
    -    for efficiently determining those complete home units that provide a
    
    11
    -    certain module name and changes the module-finding algorithm such
    
    12
    -    that it searches these units before the other home units. This leads
    
    13
    -    to significant performance improvements in situations where there
    
    14
    -    are lots of home units.
    
    6
    +    For finding out which home unit provides the module that a certain
    
    7
    +    import declaration refers to, we now use a better algorithm. The
    
    8
    +    previous approach was to simply search all home units in no
    
    9
    +    particular order. The new algorithm first searches those complete
    
    10
    +    home units that provide a certain module name, before searching the
    
    11
    +    other home units.
    
    15 12
     }

  • compiler/GHC/HsToCore/Usage.hs
    ... ... @@ -70,6 +70,8 @@ data UsageConfig = UsageConfig
    70 70
       { uc_safe_implicit_imps_req :: !Bool -- ^ Are all implicit imports required to be safe for this Safe Haskell mode?
    
    71 71
       }
    
    72 72
     
    
    73
    +-- | Build the list of 'Usage's that drive recompilation checking.
    
    74
    +-- The resulting list is deterministically sorted.
    
    73 75
     mkUsageInfo :: UsageConfig -> Plugins -> FinderCache -> UnitEnv
    
    74 76
                 -> Module -> ImportedMods -> [ImportUserSpec] -> NameSet
    
    75 77
                 -> [FilePath] -> [FilePath] -> [(Module, Fingerprint)] -> [LinkableUsage] -> PkgsLoaded
    
    ... ... @@ -100,10 +102,10 @@ mkUsageInfo uc plugins fc unit_env
    100 102
                                         }
    
    101 103
                                    | (mod, hash) <- merged ]
    
    102 104
                                 ++ object_usages
    
    103
    -    usages `seqList` return usages
    
    104
    -    -- seq the list of Usages returned: occasionally these
    
    105
    -    -- don't get evaluated for a while and we can end up hanging on to
    
    106
    -    -- the entire collection of Ifaces.
    
    105
    +    usages `seqList` return (sortBy stableUsageCmp usages)
    
    106
    +    -- The use of 'seqList' is important because occasionally the returned list
    
    107
    +    -- is not evaluated for a while, so that with too much laziness here we
    
    108
    +    -- could end up hanging on to the entire collection of 'Iface's.
    
    107 109
     
    
    108 110
     {- Note [Plugin dependencies]
    
    109 111
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

  • compiler/GHC/Unit/Module/Deps.hs
    1 1
     {-# LANGUAGE PatternSynonyms #-}
    
    2 2
     {-# LANGUAGE DerivingVia #-}
    
    3
    +
    
    4
    +{-# OPTIONS_GHC -Wwarn=incomplete-record-selectors #-}
    
    5
    +
    
    3 6
     -- | Dependencies and Usage of a module
    
    4 7
     module GHC.Unit.Module.Deps
    
    5 8
        ( Dependencies(dep_direct_mods
    
    ... ... @@ -17,6 +20,7 @@ module GHC.Unit.Module.Deps
    17 20
        , noDependencies
    
    18 21
        , pprDeps
    
    19 22
        , Usage (..)
    
    23
    +   , stableUsageCmp
    
    20 24
        , HomeModImport (..)
    
    21 25
        , HomeModImportedAvails (..)
    
    22 26
        , ImportAvails (..)
    
    ... ... @@ -52,6 +56,7 @@ import GHC.Utils.Outputable
    52 56
     import Control.DeepSeq
    
    53 57
     import Data.Bifunctor
    
    54 58
     import qualified Data.Foldable as Foldable
    
    59
    +import Data.Function (on)
    
    55 60
     import Data.List (sortBy, sort, partition)
    
    56 61
     import Data.Set (Set)
    
    57 62
     import qualified Data.Set as Set
    
    ... ... @@ -497,6 +502,47 @@ instance Binary Usage where
    497 502
     
    
    498 503
               i -> error ("Binary.get(Usage): " ++ show i)
    
    499 504
     
    
    505
    +-- | Compares 'Usage's by constructor and, if the constructors are the same, by
    
    506
    +--   identifying strings, to achieve a predictable ordering.
    
    507
    +stableUsageCmp :: Usage -> Usage -> Ordering
    
    508
    +stableUsageCmp
    
    509
    +    usage1@UsagePackageModule {}
    
    510
    +    usage2@UsagePackageModule {}
    
    511
    +    = (compare `on` usg_mod) usage1 usage2
    
    512
    +stableUsageCmp
    
    513
    +    usage1@UsageHomeModule {}
    
    514
    +    usage2@UsageHomeModule {}
    
    515
    +    = (compare `on` Module <$> usg_unit_id <*> usg_mod_name) usage1 usage2
    
    516
    +stableUsageCmp
    
    517
    +    usage1@UsageFile {}
    
    518
    +    usage2@UsageFile {}
    
    519
    +    = (lexicalCompareFS `on` usg_file_path) usage1 usage2
    
    520
    +stableUsageCmp
    
    521
    +    usage1@UsageDirectory {}
    
    522
    +    usage2@UsageDirectory {}
    
    523
    +    = (lexicalCompareFS `on` usg_dir_path) usage1 usage2
    
    524
    +stableUsageCmp
    
    525
    +    usage1@UsageHomeModuleBytecode {}
    
    526
    +    usage2@UsageHomeModuleBytecode {}
    
    527
    +    = (compare `on` Module <$> usg_unit_id <*> usg_mod_name) usage1 usage2
    
    528
    +stableUsageCmp
    
    529
    +    usage1@UsageMergedRequirement {}
    
    530
    +    usage2@UsageMergedRequirement {}
    
    531
    +    = (compare `on` usg_mod) usage1 usage2
    
    532
    +stableUsageCmp
    
    533
    +    usage1
    
    534
    +    usage2
    
    535
    +    = (compare `on` constructorIndex) usage1 usage2
    
    536
    +    where
    
    537
    +
    
    538
    +    constructorIndex :: Usage -> Int
    
    539
    +    constructorIndex UsagePackageModule      {} = 0
    
    540
    +    constructorIndex UsageHomeModule         {} = 1
    
    541
    +    constructorIndex UsageFile               {} = 2
    
    542
    +    constructorIndex UsageDirectory          {} = 3
    
    543
    +    constructorIndex UsageHomeModuleBytecode {} = 4
    
    544
    +    constructorIndex UsageMergedRequirement  {} = 5
    
    545
    +
    
    500 546
     -- | Records the imports that we depend on from a home module,
    
    501 547
     -- for recompilation checking.
    
    502 548
     --