Zubin pushed to branch wip/9.14.2-backports at Glasgow Haskell Compiler / GHC

Commits:

26 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/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/ByteCode/Breakpoints.hs
    ... ... @@ -40,7 +40,7 @@ import Control.DeepSeq
    40 40
     import Data.IntMap.Strict (IntMap)
    
    41 41
     import qualified Data.IntMap.Strict as IM
    
    42 42
     
    
    43
    -import GHC.HsToCore.Breakpoints
    
    43
    +import GHC.HsToCore.Breakpoints.Types
    
    44 44
     import GHC.Iface.Syntax
    
    45 45
     
    
    46 46
     import GHC.Unit.Module (Module)
    

  • compiler/GHC/ByteCode/Types.hs
    ... ... @@ -42,7 +42,7 @@ import GHC.Types.Name.Env
    42 42
     import GHC.Utils.Outputable
    
    43 43
     import GHC.Builtin.PrimOps
    
    44 44
     import GHC.Types.SptEntry
    
    45
    -import GHC.HsToCore.Breakpoints
    
    45
    +import GHC.HsToCore.Breakpoints.Types
    
    46 46
     import GHC.ByteCode.Breakpoints
    
    47 47
     import GHCi.Message
    
    48 48
     import GHCi.RemoteTypes
    
    ... ... @@ -305,4 +305,3 @@ instance Outputable UnlinkedBCO where
    305 305
           = sep [text "BCO", ppr nm, text "with",
    
    306 306
                  ppr (sizeFlatBag lits), text "lits",
    
    307 307
                  ppr (sizeFlatBag ptrs), text "ptrs" ]
    308
    -

  • compiler/GHC/Driver/Main.hs
    ... ... @@ -693,7 +693,7 @@ hsc_typecheck keep_rn mod_summary mb_rdr_module = do
    693 693
                         Nothing -> hscParse' mod_summary
    
    694 694
                 tc_result0 <- tcRnModule' mod_summary keep_rn' hpm
    
    695 695
                 if hsc_src == HsigFile
    
    696
    -                then do (iface, _) <- liftIO $ hscSimpleIface hsc_env Nothing tc_result0 mod_summary
    
    696
    +                then do (iface, _) <- liftIO $ hscSimpleIface hsc_env Nothing Nothing tc_result0 mod_summary
    
    697 697
                             ioMsgMaybe $ hoistTcRnMessage $
    
    698 698
                                 tcRnMergeSignatures hsc_env hpm tc_result0 iface
    
    699 699
                     else return tc_result0
    
    ... ... @@ -871,7 +871,7 @@ hscRecompStatus
    871 871
                    -- we will decide if we need them or not.
    
    872 872
                    bc_linkable <- checkByteCode checked_iface mod_summary (homeMod_bytecode old_linkable)
    
    873 873
                    obj_linkable <- liftIO $ checkObjects lcl_dflags (homeMod_object old_linkable) mod_summary
    
    874
    -               trace_if (hsc_logger hsc_env) (vcat [text "BCO linkable", nest 2 (ppr bc_linkable), text "Object Linkable", ppr obj_linkable])
    
    874
    +               trace_if (hsc_logger hsc_env) (vcat [text "BCO linkable", nest 2 (ppr bc_linkable), text "Object Linkable", nest 2 (ppr obj_linkable)])
    
    875 875
     
    
    876 876
                    let just_bc = justBytecode <$> bc_linkable
    
    877 877
                        just_o  = justObjects  <$> obj_linkable
    
    ... ... @@ -1018,12 +1018,13 @@ compile_for_interpreter hsc_env use =
    1018 1018
     -- | Assemble 'WholeCoreBindings' if the interface contains Core bindings.
    
    1019 1019
     iface_core_bindings :: ModIface -> ModLocation -> Maybe WholeCoreBindings
    
    1020 1020
     iface_core_bindings iface wcb_mod_location =
    
    1021
    -  mi_simplified_core <&> \(IfaceSimplifiedCore bindings foreign') ->
    
    1021
    +  mi_simplified_core <&> \(IfaceSimplifiedCore bindings wcb_modBreaks foreign') ->
    
    1022 1022
         WholeCoreBindings {
    
    1023 1023
           wcb_bindings = bindings,
    
    1024 1024
           wcb_module = mi_module,
    
    1025 1025
           wcb_mod_location,
    
    1026
    -      wcb_foreign = foreign'
    
    1026
    +      wcb_foreign = foreign',
    
    1027
    +      wcb_modBreaks
    
    1027 1028
         }
    
    1028 1029
       where
    
    1029 1030
         ModIface {mi_module, mi_simplified_core} = iface
    
    ... ... @@ -1161,11 +1162,11 @@ compileWholeCoreBindings hsc_env type_env wcb = do
    1161 1162
         gen_bytecode core_binds stubs foreign_files = do
    
    1162 1163
           let cgi_guts = CgInteractiveGuts wcb_module core_binds
    
    1163 1164
                           (typeEnvTyCons type_env) stubs foreign_files
    
    1164
    -                      Nothing []
    
    1165
    +                      wcb_modBreaks []
    
    1165 1166
           trace_if logger (text "Generating ByteCode for" <+> ppr wcb_module)
    
    1166 1167
           generateByteCode hsc_env cgi_guts wcb_mod_location
    
    1167 1168
     
    
    1168
    -    WholeCoreBindings {wcb_module, wcb_mod_location, wcb_foreign} = wcb
    
    1169
    +    WholeCoreBindings {wcb_module, wcb_mod_location, wcb_foreign, wcb_modBreaks} = wcb
    
    1169 1170
     
    
    1170 1171
         logger = hsc_logger hsc_env
    
    1171 1172
     
    
    ... ... @@ -1292,7 +1293,8 @@ hscDesugarAndSimplify summary (FrontendTypecheck tc_result) tc_warnings mb_old_h
    1292 1293
                   liftIO $ hscTidy hsc_env simplified_guts
    
    1293 1294
     
    
    1294 1295
               (iface, _details) <- liftIO $
    
    1295
    -            hscSimpleIface hsc_env (Just $ cg_binds cg_guts) tc_result summary
    
    1296
    +            hscSimpleIface hsc_env (Just $ cg_binds cg_guts)
    
    1297
    +             (cg_modBreaks cg_guts) tc_result summary
    
    1296 1298
     
    
    1297 1299
               liftIO $ hscMaybeWriteIface logger dflags True iface mb_old_hash (ms_location summary)
    
    1298 1300
     
    
    ... ... @@ -1307,7 +1309,7 @@ hscDesugarAndSimplify summary (FrontendTypecheck tc_result) tc_warnings mb_old_h
    1307 1309
           -- and generate a simple interface.
    
    1308 1310
           _ -> do
    
    1309 1311
             (iface, _details) <- liftIO $
    
    1310
    -          hscSimpleIface hsc_env Nothing tc_result summary
    
    1312
    +          hscSimpleIface hsc_env Nothing Nothing tc_result summary
    
    1311 1313
     
    
    1312 1314
             liftIO $ hscMaybeWriteIface logger dflags True iface mb_old_hash (ms_location summary)
    
    1313 1315
     
    
    ... ... @@ -1886,17 +1888,19 @@ hscSimplify' plugins ds_result = do
    1886 1888
     -- generates interface files. See Note [simpleTidyPgm - mkBootModDetailsTc]
    
    1887 1889
     hscSimpleIface :: HscEnv
    
    1888 1890
                    -> Maybe CoreProgram
    
    1891
    +               -> Maybe ModBreaks
    
    1889 1892
                    -> TcGblEnv
    
    1890 1893
                    -> ModSummary
    
    1891 1894
                    -> IO (ModIface, ModDetails)
    
    1892
    -hscSimpleIface hsc_env mb_core_program tc_result summary
    
    1893
    -    = runHsc hsc_env $ hscSimpleIface' mb_core_program tc_result summary
    
    1895
    +hscSimpleIface hsc_env mb_core_program mb_modBreaks tc_result summary
    
    1896
    +    = runHsc hsc_env $ hscSimpleIface' mb_core_program mb_modBreaks tc_result summary
    
    1894 1897
     
    
    1895 1898
     hscSimpleIface' :: Maybe CoreProgram
    
    1899
    +                -> Maybe ModBreaks
    
    1896 1900
                     -> TcGblEnv
    
    1897 1901
                     -> ModSummary
    
    1898 1902
                     -> Hsc (ModIface, ModDetails)
    
    1899
    -hscSimpleIface' mb_core_program tc_result summary = do
    
    1903
    +hscSimpleIface' mb_core_program mb_modBreaks tc_result summary = do
    
    1900 1904
         hsc_env   <- getHscEnv
    
    1901 1905
         logger    <- getLogger
    
    1902 1906
         details   <- liftIO $ mkBootModDetailsTc logger tc_result
    
    ... ... @@ -1904,7 +1908,7 @@ hscSimpleIface' mb_core_program tc_result summary = do
    1904 1908
         new_iface
    
    1905 1909
             <- {-# SCC "MkFinalIface" #-}
    
    1906 1910
                liftIO $
    
    1907
    -               mkIfaceTc hsc_env safe_mode details summary mb_core_program tc_result
    
    1911
    +               mkIfaceTc hsc_env safe_mode details summary mb_core_program mb_modBreaks tc_result
    
    1908 1912
         -- And the answer is ...
    
    1909 1913
         liftIO $ dumpIfaceStats hsc_env
    
    1910 1914
         return (new_iface, details)
    

  • compiler/GHC/HsToCore/Breakpoints.hs
    ... ... @@ -15,7 +15,7 @@
    15 15
     -- See Note [ModBreaks vs InternalModBreaks] and Note [Breakpoint identifiers]
    
    16 16
     module GHC.HsToCore.Breakpoints
    
    17 17
       ( -- * ModBreaks
    
    18
    -    mkModBreaks, ModBreaks(..)
    
    18
    +    mkModBreaks, ModBreaks(..), modBreaks_locs
    
    19 19
     
    
    20 20
         -- ** Re-exports BreakpointId
    
    21 21
       , BreakpointId(..), BreakTickIndex
    
    ... ... @@ -25,46 +25,12 @@ import GHC.Prelude
    25 25
     import Data.Array
    
    26 26
     
    
    27 27
     import GHC.HsToCore.Ticks (Tick (..))
    
    28
    +import GHC.HsToCore.Breakpoints.Types
    
    28 29
     import GHC.Data.SizedSeq
    
    29
    -import GHC.Types.SrcLoc (SrcSpan)
    
    30
    -import GHC.Types.Name (OccName)
    
    31
    -import GHC.Types.Tickish (BreakTickIndex, BreakpointId(..))
    
    32 30
     import GHC.Unit.Module (Module)
    
    33 31
     import GHC.Utils.Outputable
    
    34 32
     import Data.List (intersperse)
    
    35
    -
    
    36
    ---------------------------------------------------------------------------------
    
    37
    --- ModBreaks
    
    38
    ---------------------------------------------------------------------------------
    
    39
    -
    
    40
    --- | All the information about the source-relevant breakpoints for a module
    
    41
    ---
    
    42
    --- This information is constructed once during desugaring (with `mkModBreaks`)
    
    43
    --- from breakpoint ticks and fixed/unchanged from there on forward. It could be
    
    44
    --- exported as an abstract datatype because it should never be updated after
    
    45
    --- construction, only queried.
    
    46
    ---
    
    47
    --- The arrays can be indexed using the int in the corresponding 'BreakpointId'
    
    48
    --- (i.e. the 'BreakpointId' whose 'Module' matches the 'Module' corresponding
    
    49
    --- to these 'ModBreaks') with the accessors 'modBreaks_locs', 'modBreaks_vars',
    
    50
    --- and 'modBreaks_decls'.
    
    51
    -data ModBreaks
    
    52
    -   = ModBreaks
    
    53
    -   { modBreaks_locs   :: !(Array BreakTickIndex SrcSpan)
    
    54
    -        -- ^ An array giving the source span of each breakpoint.
    
    55
    -   , modBreaks_vars   :: !(Array BreakTickIndex [OccName])
    
    56
    -        -- ^ An array giving the names of the free variables at each breakpoint.
    
    57
    -   , modBreaks_decls  :: !(Array BreakTickIndex [String])
    
    58
    -        -- ^ An array giving the names of the declarations enclosing each breakpoint.
    
    59
    -        -- See Note [Field modBreaks_decls]
    
    60
    -   , modBreaks_ccs    :: !(Array BreakTickIndex (String, String))
    
    61
    -        -- ^ Array pointing to cost centre info for each breakpoint;
    
    62
    -        -- actual 'CostCentre' allocation is done at link-time.
    
    63
    -   , modBreaks_module :: !Module
    
    64
    -        -- ^ The module to which this ModBreaks is associated.
    
    65
    -        -- We also cache this here for internal sanity checks.
    
    66
    -   }
    
    67
    -
    
    33
    +import GHC.Utils.Binary (BinSrcSpan(BinSrcSpan))
    
    68 34
     -- | Initialize memory for breakpoint data that is shared between the bytecode
    
    69 35
     -- generator and the interpreter.
    
    70 36
     --
    
    ... ... @@ -91,7 +57,7 @@ mkModBreaks interpreterProfiled modl extendedMixEntries
    91 57
                     ]
    
    92 58
               | otherwise = listArray (0, -1) []
    
    93 59
          in ModBreaks
    
    94
    -      { modBreaks_locs   = locsTicks
    
    60
    +      { modBreaks_locs_  = fmap BinSrcSpan locsTicks
    
    95 61
           , modBreaks_vars   = varsTicks
    
    96 62
           , modBreaks_decls  = declsTicks
    
    97 63
           , modBreaks_ccs    = ccs
    

  • compiler/GHC/HsToCore/Breakpoints/Types.hs
    1
    +{-# LANGUAGE RecordWildCards #-}
    
    2
    +
    
    3
    +-- | Information attached to Breakpoints generated from Ticks
    
    4
    +--
    
    5
    +-- The breakpoint information stored in 'ModBreaks' is generated during
    
    6
    +-- desugaring from the ticks annotating the source expressions.
    
    7
    +--
    
    8
    +-- This information can be queried per-breakpoint using the 'BreakpointId'
    
    9
    +-- datatype, which indexes tick-level breakpoint information.
    
    10
    +--
    
    11
    +-- 'ModBreaks' and 'BreakpointId's are not to be confused with
    
    12
    +-- 'InternalModBreaks' and 'InternalBreakId's. The latter are constructed
    
    13
    +-- during bytecode generation and can be found in 'GHC.ByteCode.Breakpoints'.
    
    14
    +--
    
    15
    +-- See Note [ModBreaks vs InternalModBreaks] and Note [Breakpoint identifiers]
    
    16
    +module GHC.HsToCore.Breakpoints.Types
    
    17
    +  ( -- * ModBreaks
    
    18
    +    ModBreaks(..), modBreaks_locs
    
    19
    +
    
    20
    +    -- ** Re-exports BreakpointId
    
    21
    +  , BreakpointId(..), BreakTickIndex
    
    22
    +  ) where
    
    23
    +
    
    24
    +import GHC.Prelude
    
    25
    +import Data.Array
    
    26
    +
    
    27
    +import GHC.Types.SrcLoc (SrcSpan)
    
    28
    +import GHC.Types.Name (OccName)
    
    29
    +import GHC.Types.Tickish (BreakTickIndex, BreakpointId(..))
    
    30
    +import GHC.Unit.Module (Module)
    
    31
    +import Data.Coerce
    
    32
    +import GHC.Utils.Binary (BinSrcSpan(..), Binary(..))
    
    33
    +import Control.DeepSeq
    
    34
    +
    
    35
    +--------------------------------------------------------------------------------
    
    36
    +-- ModBreaks
    
    37
    +--------------------------------------------------------------------------------
    
    38
    +
    
    39
    +-- | All the information about the source-relevant breakpoints for a module
    
    40
    +--
    
    41
    +-- This information is constructed once during desugaring (with `mkModBreaks`)
    
    42
    +-- from breakpoint ticks and fixed/unchanged from there on forward. It could be
    
    43
    +-- exported as an abstract datatype because it should never be updated after
    
    44
    +-- construction, only queried.
    
    45
    +--
    
    46
    +-- The arrays can be indexed using the int in the corresponding 'BreakpointId'
    
    47
    +-- (i.e. the 'BreakpointId' whose 'Module' matches the 'Module' corresponding
    
    48
    +-- to these 'ModBreaks') with the accessors 'modBreaks_locs', 'modBreaks_vars',
    
    49
    +-- and 'modBreaks_decls'.
    
    50
    +data ModBreaks
    
    51
    +   = ModBreaks
    
    52
    +   { modBreaks_locs_   :: !(Array BreakTickIndex BinSrcSpan)
    
    53
    +        -- ^ An array giving the source span of each breakpoint.
    
    54
    +   , modBreaks_vars   :: !(Array BreakTickIndex [OccName])
    
    55
    +        -- ^ An array giving the names of the free variables at each breakpoint.
    
    56
    +   , modBreaks_decls  :: !(Array BreakTickIndex [String])
    
    57
    +        -- ^ An array giving the names of the declarations enclosing each breakpoint.
    
    58
    +        -- See Note [Field modBreaks_decls]
    
    59
    +   , modBreaks_ccs    :: !(Array BreakTickIndex (String, String))
    
    60
    +        -- ^ Array pointing to cost centre info for each breakpoint;
    
    61
    +        -- actual 'CostCentre' allocation is done at link-time.
    
    62
    +   , modBreaks_module :: !Module
    
    63
    +        -- ^ The module to which this ModBreaks is associated.
    
    64
    +        -- We also cache this here for internal sanity checks.
    
    65
    +   }
    
    66
    +
    
    67
    +modBreaks_locs :: ModBreaks -> Array BreakTickIndex SrcSpan
    
    68
    +modBreaks_locs = coerce . modBreaks_locs_
    
    69
    +
    
    70
    +instance Binary ModBreaks where
    
    71
    +  get bh = ModBreaks <$> get bh <*> get bh <*> get bh <*> get bh <*> get bh
    
    72
    +
    
    73
    +  put_ bh ModBreaks {..} =
    
    74
    +    put_ bh modBreaks_locs_
    
    75
    +      *> put_ bh modBreaks_vars
    
    76
    +      *> put_ bh modBreaks_decls
    
    77
    +      *> put_ bh modBreaks_ccs
    
    78
    +      *> put_ bh modBreaks_module
    
    79
    +
    
    80
    +instance NFData ModBreaks where
    
    81
    +  rnf (ModBreaks a b c d e) = rnf a `seq` rnf b `seq` rnf c `seq` rnf d `seq` rnf e
    \ No newline at end of file

  • compiler/GHC/HsToCore/Usage.hs
    ... ... @@ -73,6 +73,8 @@ data UsageConfig = UsageConfig
    73 73
       { uc_safe_implicit_imps_req :: !Bool -- ^ Are all implicit imports required to be safe for this Safe Haskell mode?
    
    74 74
       }
    
    75 75
     
    
    76
    +-- | Build the list of 'Usage's that drive recompilation checking.
    
    77
    +-- The resulting list is deterministically sorted.
    
    76 78
     mkUsageInfo :: UsageConfig -> Plugins -> FinderCache -> UnitEnv
    
    77 79
                 -> Module -> ImportedMods -> [ImportUserSpec] -> NameSet
    
    78 80
                 -> [FilePath] -> [(Module, Fingerprint)] -> [Linkable] -> 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/Iface/Load.hs
    ... ... @@ -62,6 +62,8 @@ import GHC.Iface.Rename
    62 62
     import GHC.Iface.Env
    
    63 63
     import GHC.Iface.Errors as Iface_Errors
    
    64 64
     
    
    65
    +import GHC.HsToCore.Breakpoints.Types (modBreaks_locs)
    
    66
    +
    
    65 67
     import GHC.Tc.Errors.Types
    
    66 68
     import GHC.Tc.Utils.Monad
    
    67 69
     
    
    ... ... @@ -112,6 +114,7 @@ import GHC.Unit.Env
    112 114
     import GHC.Data.Maybe
    
    113 115
     
    
    114 116
     import Control.Monad
    
    117
    +import qualified Data.Foldable as Foldable
    
    115 118
     import Data.Map ( toList )
    
    116 119
     import System.FilePath
    
    117 120
     import System.Directory
    
    ... ... @@ -1159,9 +1162,11 @@ pprModIface unit_state iface
    1159 1162
             , vcat [ppr ver $$ nest 2 (ppr decl) | (ver,decl) <- mi_decls iface]
    
    1160 1163
             , case mi_simplified_core iface of
    
    1161 1164
                 Nothing -> empty
    
    1162
    -            Just (IfaceSimplifiedCore eds fs) ->
    
    1165
    +            Just (IfaceSimplifiedCore eds mbs fs) ->
    
    1163 1166
                   vcat [ text "extra decls:"
    
    1164 1167
                                $$ nest 2 (vcat ([ppr bs | bs <- eds]))
    
    1168
    +                   , text "mod breaks:"
    
    1169
    +                           $$ nest 2 (ppr $ Foldable.toList . modBreaks_locs <$> mbs)
    
    1165 1170
                        , text "foreign stubs:"
    
    1166 1171
                                $$ nest 2 (ppr fs)
    
    1167 1172
                        ]
    

  • compiler/GHC/Iface/Make.hs
    ... ... @@ -34,6 +34,7 @@ import GHC.Iface.Syntax
    34 34
     import GHC.Iface.Recomp
    
    35 35
     import GHC.Iface.Load
    
    36 36
     import GHC.Iface.Ext.Fields
    
    37
    +import GHC.HsToCore.Breakpoints.Types (ModBreaks)
    
    37 38
     
    
    38 39
     import GHC.CoreToIface
    
    39 40
     
    
    ... ... @@ -122,11 +123,12 @@ mkPartialIface hsc_env core_prog mod_details mod_summary import_decls
    122 123
              , mg_safe_haskell = safe_mode
    
    123 124
              , mg_trust_pkg    = self_trust
    
    124 125
              , mg_docs         = docs
    
    126
    +         , mg_modBreaks    = modBreaks
    
    125 127
              }
    
    126 128
       = do
    
    127 129
           self_recomp <- traverse (mkSelfRecomp hsc_env this_mod (ms_hs_hash mod_summary)) usages
    
    128 130
           return $ mkIface_ hsc_env this_mod core_prog hsc_src deps rdr_env import_decls fix_env warns self_trust
    
    129
    -                safe_mode self_recomp docs mod_details
    
    131
    +                safe_mode self_recomp docs mod_details modBreaks
    
    130 132
     
    
    131 133
     -- | Fully instantiate an interface. Adds fingerprints and potentially code
    
    132 134
     -- generator produced information.
    
    ... ... @@ -228,9 +230,10 @@ mkIfaceTc :: HscEnv
    228 230
               -> ModDetails         -- gotten from mkBootModDetails, probably
    
    229 231
               -> ModSummary
    
    230 232
               -> Maybe CoreProgram
    
    233
    +          -> Maybe ModBreaks
    
    231 234
               -> TcGblEnv           -- Usages, deprecations, etc
    
    232 235
               -> IO ModIface
    
    233
    -mkIfaceTc hsc_env safe_mode mod_details mod_summary mb_program
    
    236
    +mkIfaceTc hsc_env safe_mode mod_details mod_summary mb_program mb_modBreaks
    
    234 237
       tc_result@TcGblEnv{ tcg_mod = this_mod,
    
    235 238
                           tcg_src = hsc_src,
    
    236 239
                           tcg_imports = imports,
    
    ... ... @@ -258,6 +261,7 @@ mkIfaceTc hsc_env safe_mode mod_details mod_summary mb_program
    258 261
                        (imp_trust_own_pkg imports) safe_mode self_recomp
    
    259 262
                        docs
    
    260 263
                        mod_details
    
    264
    +                   mb_modBreaks
    
    261 265
     
    
    262 266
               mkFullIface hsc_env partial_iface Nothing Nothing NoStubs []
    
    263 267
     
    
    ... ... @@ -302,6 +306,7 @@ mkIface_ :: HscEnv -> Module -> CoreProgram -> HscSource
    302 306
              -> Maybe IfaceSelfRecomp
    
    303 307
              -> Maybe Docs
    
    304 308
              -> ModDetails
    
    309
    +         -> Maybe ModBreaks
    
    305 310
              -> PartialModIface
    
    306 311
     mkIface_ hsc_env
    
    307 312
              this_mod core_prog hsc_src deps rdr_env import_decls fix_env src_warns
    
    ... ... @@ -319,15 +324,17 @@ mkIface_ hsc_env
    319 324
     --      only at the TypeEnv.  The previous Tidy phase has
    
    320 325
     --      put exactly the info into the TypeEnv that we want
    
    321 326
     --      to expose in the interface
    
    322
    -
    
    327
    +        modBreaks
    
    323 328
       = do
    
    324 329
         let home_unit    = hsc_home_unit hsc_env
    
    325 330
             semantic_mod = homeModuleNameInstantiation home_unit (moduleName this_mod)
    
    326 331
             entities = typeEnvElts type_env
    
    327 332
             show_linear_types = xopt LangExt.LinearTypes (hsc_dflags hsc_env)
    
    328 333
     
    
    329
    -        simplified_core = if gopt Opt_WriteIfSimplifiedCore dflags then Just (IfaceSimplifiedCore [ toIfaceTopBind b | b <- core_prog ] emptyIfaceForeign)
    
    330
    -                                                                   else Nothing
    
    334
    +        simplified_core =
    
    335
    +          if gopt Opt_WriteIfSimplifiedCore dflags
    
    336
    +          then Just (IfaceSimplifiedCore [ toIfaceTopBind b | b <- core_prog ] modBreaks emptyIfaceForeign)
    
    337
    +          else Nothing
    
    331 338
             decls  = [ tyThingToIfaceDecl show_linear_types entity
    
    332 339
                      | entity <- entities,
    
    333 340
                        let name = getName entity,
    

  • compiler/GHC/Iface/Recomp.hs
    ... ... @@ -1208,7 +1208,7 @@ addFingerprints hsc_env iface0 = do
    1208 1208
     
    
    1209 1209
           sorted_extra_decls :: Maybe IfaceSimplifiedCore
    
    1210 1210
           sorted_extra_decls = mi_simplified_core iface0 <&> \simpl_core ->
    
    1211
    -         IfaceSimplifiedCore (sortOn binding_key (mi_sc_extra_decls simpl_core)) (mi_sc_foreign simpl_core)
    
    1211
    +         IfaceSimplifiedCore (sortOn binding_key (mi_sc_extra_decls simpl_core)) (mi_sc_modBreaks simpl_core) (mi_sc_foreign simpl_core)
    
    1212 1212
     
    
    1213 1213
       -- The interface hash depends on:
    
    1214 1214
       --   - the ABI hash, plus
    

  • compiler/GHC/Linker/Types.hs
    ... ... @@ -47,6 +47,7 @@ module GHC.Linker.Types
    47 47
        , linkableFilterByteCode
    
    48 48
        , linkableFilterNative
    
    49 49
        , partitionLinkables
    
    50
    +   , linkableAllBCOs
    
    50 51
        )
    
    51 52
     where
    
    52 53
     
    
    ... ... @@ -352,6 +353,17 @@ linkableIsNativeCodeOnly l = all isNativeCode (NE.toList (linkableParts l))
    352 353
     linkableBCOs :: Linkable -> [CompiledByteCode]
    
    353 354
     linkableBCOs l = [ cbc | BCOs cbc <- NE.toList (linkableParts l) ]
    
    354 355
     
    
    356
    +linkableAllBCOs :: Linkable -> [CompiledByteCode]
    
    357
    +linkableAllBCOs l = mapMaybe bcos $ NE.toList (linkableParts l)
    
    358
    +  where
    
    359
    +    -- Note: explicit match on all constructors to trigger warning when new ones are introduced.
    
    360
    +    bcos (BCOs bco) = Just bco
    
    361
    +    bcos (LazyBCOs bco _fs) = Just bco -- TODO: _fs ?
    
    362
    +    bcos DotA{} = Nothing
    
    363
    +    bcos DotDLL{} = Nothing
    
    364
    +    bcos CoreBindings{} = Nothing
    
    365
    +    bcos DotO{} = Nothing
    
    366
    +
    
    355 367
     -- | List the native linkable parts (.o/.so/.dll) of a linkable
    
    356 368
     linkableNativeParts :: Linkable -> [LinkablePart]
    
    357 369
     linkableNativeParts l = NE.filter isNativeCode (linkableParts l)
    

  • compiler/GHC/Runtime/Interpreter.hs
    ... ... @@ -737,7 +737,7 @@ getModBreaks :: HomeModInfo -> Maybe InternalModBreaks
    737 737
     getModBreaks hmi
    
    738 738
       | Just linkable <- homeModInfoByteCode hmi,
    
    739 739
         -- The linkable may have 'DotO's as well; only consider BCOs. See #20570.
    
    740
    -    [cbc] <- linkableBCOs linkable
    
    740
    +    [cbc] <- linkableAllBCOs linkable
    
    741 741
       = bc_breaks cbc
    
    742 742
       | otherwise
    
    743 743
       = Nothing -- probably object code
    

  • compiler/GHC/Unit/Module/Deps.hs
    ... ... @@ -2,6 +2,9 @@
    2 2
     {-# LANGUAGE PatternSynonyms #-}
    
    3 3
     {-# LANGUAGE ExplicitNamespaces #-}
    
    4 4
     {-# LANGUAGE DerivingVia #-}
    
    5
    +
    
    6
    +{-# OPTIONS_GHC -Wwarn=incomplete-record-selectors #-}
    
    7
    +
    
    5 8
     -- | Dependencies and Usage of a module
    
    6 9
     module GHC.Unit.Module.Deps
    
    7 10
        ( Dependencies(dep_direct_mods
    
    ... ... @@ -19,6 +22,7 @@ module GHC.Unit.Module.Deps
    19 22
        , noDependencies
    
    20 23
        , pprDeps
    
    21 24
        , Usage (..)
    
    25
    +   , stableUsageCmp
    
    22 26
        , HomeModImport (..)
    
    23 27
        , HomeModImportedAvails (..)
    
    24 28
        , ImportAvails (..)
    
    ... ... @@ -45,6 +49,7 @@ import GHC.Utils.Fingerprint
    45 49
     import GHC.Utils.Binary
    
    46 50
     import GHC.Utils.Outputable
    
    47 51
     
    
    52
    +import Data.Function (on)
    
    48 53
     import Data.List (sortBy, sort, partition)
    
    49 54
     import Data.Set (Set)
    
    50 55
     import qualified Data.Set as Set
    
    ... ... @@ -464,6 +469,42 @@ instance Binary Usage where
    464 469
                 return UsageHomeModuleInterface { usg_mod_name = mod, usg_unit_id = uid, usg_iface_hash = hash }
    
    465 470
               i -> error ("Binary.get(Usage): " ++ show i)
    
    466 471
     
    
    472
    +-- | Compares 'Usage's by constructor and, if the constructors are the same, by
    
    473
    +--   identifying strings, to achieve a predictable ordering.
    
    474
    +stableUsageCmp :: Usage -> Usage -> Ordering
    
    475
    +stableUsageCmp
    
    476
    +    usage1@UsagePackageModule {}
    
    477
    +    usage2@UsagePackageModule {}
    
    478
    +    = (compare `on` usg_mod) usage1 usage2
    
    479
    +stableUsageCmp
    
    480
    +    usage1@UsageHomeModule {}
    
    481
    +    usage2@UsageHomeModule {}
    
    482
    +    = (compare `on` Module <$> usg_unit_id <*> usg_mod_name) usage1 usage2
    
    483
    +stableUsageCmp
    
    484
    +    usage1@UsageFile {}
    
    485
    +    usage2@UsageFile {}
    
    486
    +    = (lexicalCompareFS `on` usg_file_path) usage1 usage2
    
    487
    +stableUsageCmp
    
    488
    +    usage1@UsageHomeModuleInterface {}
    
    489
    +    usage2@UsageHomeModuleInterface {}
    
    490
    +    = (compare `on` Module <$> usg_unit_id <*> usg_mod_name) usage1 usage2
    
    491
    +stableUsageCmp
    
    492
    +    usage1@UsageMergedRequirement {}
    
    493
    +    usage2@UsageMergedRequirement {}
    
    494
    +    = (compare `on` usg_mod) usage1 usage2
    
    495
    +stableUsageCmp
    
    496
    +    usage1
    
    497
    +    usage2
    
    498
    +    = (compare `on` constructorIndex) usage1 usage2
    
    499
    +    where
    
    500
    +
    
    501
    +    constructorIndex :: Usage -> Int
    
    502
    +    constructorIndex UsagePackageModule       {} = 0
    
    503
    +    constructorIndex UsageHomeModule          {} = 1
    
    504
    +    constructorIndex UsageFile                {} = 2
    
    505
    +    constructorIndex UsageHomeModuleInterface {} = 3
    
    506
    +    constructorIndex UsageMergedRequirement   {} = 4
    
    507
    +
    
    467 508
     -- | Records the imports that we depend on from a home module,
    
    468 509
     -- for recompilation checking.
    
    469 510
     --
    

  • compiler/GHC/Unit/Module/ModGuts.hs
    ... ... @@ -7,7 +7,7 @@ where
    7 7
     
    
    8 8
     import GHC.Prelude
    
    9 9
     
    
    10
    -import GHC.HsToCore.Breakpoints
    
    10
    +import GHC.HsToCore.Breakpoints.Types
    
    11 11
     import GHC.ForeignSrcLang
    
    12 12
     
    
    13 13
     import GHC.Hs
    

  • compiler/GHC/Unit/Module/ModIface.hs
    ... ... @@ -127,6 +127,8 @@ import GHC.Iface.Flags
    127 127
     import GHC.Iface.Ext.Fields
    
    128 128
     import GHC.Iface.Recomp.Types
    
    129 129
     
    
    130
    +import GHC.HsToCore.Breakpoints.Types
    
    131
    +
    
    130 132
     import GHC.Unit
    
    131 133
     import GHC.Unit.Module.Deps
    
    132 134
     import GHC.Unit.Module.Warnings
    
    ... ... @@ -425,6 +427,8 @@ data IfaceSimplifiedCore = IfaceSimplifiedCore {
    425 427
       -- ^ Extra variable definitions which are **NOT** exposed but when
    
    426 428
       -- combined with mi_decls allows us to restart code generation.
    
    427 429
       -- See Note [Interface Files with Core Definitions] and Note [Interface File with Core: Sharing RHSs]
    
    430
    +  , mi_sc_modBreaks :: Maybe ModBreaks
    
    431
    +  -- ^ If breakpoints are present in @mi_sc_extra_decls@ this field provides this field provides the metadata required by the bytecode debugger.
    
    428 432
       , mi_sc_foreign :: IfaceForeign
    
    429 433
       -- ^ Foreign stubs and files to supplement 'mi_extra_decls_'.
    
    430 434
       -- See Note [Foreign stubs and TH bytecode linking]
    
    ... ... @@ -754,14 +758,16 @@ instance Binary IfaceAbiHashes where
    754 758
                        }
    
    755 759
     
    
    756 760
     instance Binary IfaceSimplifiedCore where
    
    757
    -  put_ bh (IfaceSimplifiedCore eds fs) = do
    
    761
    +  put_ bh (IfaceSimplifiedCore eds mbs fs) = do
    
    758 762
         put_ bh eds
    
    763
    +    put_ bh mbs
    
    759 764
         put_ bh fs
    
    760 765
     
    
    761 766
       get bh = do
    
    762 767
         eds <- get bh
    
    768
    +    mbs <- get bh
    
    763 769
         fs <- get bh
    
    764
    -    return (IfaceSimplifiedCore eds fs)
    
    770
    +    return (IfaceSimplifiedCore eds mbs fs)
    
    765 771
     
    
    766 772
     emptyPartialModIface :: Module -> PartialModIface
    
    767 773
     emptyPartialModIface mod
    
    ... ... @@ -870,7 +876,7 @@ instance NFData IfaceModInfo where
    870 876
     
    
    871 877
     
    
    872 878
     instance NFData IfaceSimplifiedCore where
    
    873
    -  rnf (IfaceSimplifiedCore eds fs) = rnf eds `seq` rnf fs
    
    879
    +  rnf (IfaceSimplifiedCore eds mbs fs) = rnf eds `seq` rnf mbs `seq` rnf fs
    
    874 880
     
    
    875 881
     instance NFData IfaceAbiHashes where
    
    876 882
       rnf (IfaceAbiHashes a1 a2 a3 a4 a5 a6)
    

  • compiler/GHC/Unit/Module/WholeCoreBindings.hs
    ... ... @@ -9,6 +9,7 @@ import GHC.Cmm.CLabel
    9 9
     import GHC.Driver.DynFlags (DynFlags (targetPlatform), initSDocContext)
    
    10 10
     import GHC.ForeignSrcLang (ForeignSrcLang (..))
    
    11 11
     import GHC.Iface.Syntax
    
    12
    +import GHC.HsToCore.Breakpoints.Types (ModBreaks)
    
    12 13
     import GHC.Prelude
    
    13 14
     import GHC.Types.ForeignStubs
    
    14 15
     import GHC.Unit.Module.Location
    
    ... ... @@ -127,6 +128,7 @@ the object files.
    127 128
     
    
    128 129
     data WholeCoreBindings = WholeCoreBindings
    
    129 130
                 { wcb_bindings :: [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] -- ^ serialised tidied core bindings.
    
    131
    +            , wcb_modBreaks :: Maybe ModBreaks -- ^ if @wcb_bindings@ contains breakpoints, this field provides the metadata required by the bytecode debugger.
    
    130 132
                 , wcb_module   :: Module  -- ^ The module which the bindings are for
    
    131 133
                 , wcb_mod_location :: ModLocation -- ^ The location where the sources reside.
    
    132 134
                   -- | Stubs for foreign declarations and files added via
    

  • compiler/GHC/Utils/Binary.hs
    ... ... @@ -1919,6 +1919,7 @@ instance Binary UnhelpfulSpanReason where
    1919 1919
           _ -> UnhelpfulOther <$> get bh
    
    1920 1920
     
    
    1921 1921
     newtype BinSrcSpan = BinSrcSpan { unBinSrcSpan :: SrcSpan }
    
    1922
    +  deriving newtype NFData
    
    1922 1923
     
    
    1923 1924
     -- See Note [Source Location Wrappers]
    
    1924 1925
     instance Binary BinSrcSpan where
    

  • compiler/ghc.cabal.in
    ... ... @@ -574,6 +574,7 @@ Library
    574 574
             GHC.HsToCore.Arrows
    
    575 575
             GHC.HsToCore.Binds
    
    576 576
             GHC.HsToCore.Breakpoints
    
    577
    +        GHC.HsToCore.Breakpoints.Types
    
    577 578
             GHC.HsToCore.Coverage
    
    578 579
             GHC.HsToCore.Docs
    
    579 580
             GHC.HsToCore.Errors.Ppr
    

  • testsuite/tests/count-deps/CountDepsAst.stdout
    ... ... @@ -105,6 +105,7 @@ GHC.Hs.Pat
    105 105
     GHC.Hs.Specificity
    
    106 106
     GHC.Hs.Type
    
    107 107
     GHC.Hs.Utils
    
    108
    +GHC.HsToCore.Breakpoints.Types
    
    108 109
     GHC.Iface.Errors.Types
    
    109 110
     GHC.Iface.Ext.Fields
    
    110 111
     GHC.Iface.Flags
    

  • testsuite/tests/count-deps/CountDepsParser.stdout
    ... ... @@ -109,6 +109,7 @@ GHC.Hs.Pat
    109 109
     GHC.Hs.Specificity
    
    110 110
     GHC.Hs.Type
    
    111 111
     GHC.Hs.Utils
    
    112
    +GHC.HsToCore.Breakpoints.Types
    
    112 113
     GHC.HsToCore.Errors.Types
    
    113 114
     GHC.HsToCore.Pmc.Solver.Types
    
    114 115
     GHC.Iface.Errors.Types
    

  • testsuite/tests/ghci/scripts/ListTuplePunsPpr.stdout
    ... ... @@ -24,9 +24,9 @@ instance Monad Solo -- Defined in ‘GHC.Internal.Base’
    24 24
     instance Bounded a => Bounded (Solo a)
    
    25 25
       -- Defined in ‘GHC.Internal.Enum’
    
    26 26
     instance Enum a => Enum (Solo a) -- Defined in ‘GHC.Internal.Enum’
    
    27
    -instance Read a => Read (Solo a) -- Defined in ‘GHC.Internal.Read’
    
    28 27
     instance Eq a => Eq (Solo a) -- Defined in ‘GHC.Internal.Classes’
    
    29 28
     instance Ord a => Ord (Solo a) -- Defined in ‘GHC.Internal.Classes’
    
    29
    +instance Read a => Read (Solo a) -- Defined in ‘GHC.Internal.Read’
    
    30 30
     instance Show a => Show (Solo a) -- Defined in ‘GHC.Internal.Show’
    
    31 31
     instance Monoid a => Monoid (Solo a)
    
    32 32
       -- Defined in ‘GHC.Internal.Base’
    

  • testsuite/tests/ghci/should_run/Makefile
    ... ... @@ -13,3 +13,7 @@ TopEnvIface:
    13 13
     	# Second compilation starts from interface files, but still can print "a"
    
    14 14
     	"$(TEST_HC)" $(TEST_HC_OPTS_INTERACTIVE) TopEnvIface -v1 -e "a" -e ":q" -fwrite-if-simplified-core -fwrite-interface
    
    15 15
     
    
    16
    +T27287:
    
    17
    +	"$(TEST_HC)" $(TEST_HC_OPTS_INTERACTIVE) T27287.hs -v1 -fno-hide-source-paths -e ":q" -fwrite-if-simplified-core -fwrite-interface
    
    18
    +	# Second compilation starts from interface files, but still can print "a"
    
    19
    +	"$(TEST_HC)" $(TEST_HC_OPTS_INTERACTIVE) T27287.hs -v1 -fno-hide-source-paths -e ":break T27287 5" -e ":q" -fwrite-if-simplified-core -fwrite-interface

  • testsuite/tests/ghci/should_run/T27287.hs
    1
    +module T27287 where
    
    2
    +
    
    3
    +myfun :: String -> String
    
    4
    +myfun xs = case reverse xs of
    
    5
    +  [] -> "empty"
    
    6
    +  xy -> xy

  • testsuite/tests/ghci/should_run/T27287.stdout
    1
    +[1 of 1] Compiling T27287           ( T27287.hs, interpreted )[main]
    
    2
    +Ok, one module loaded.
    
    3
    +Leaving GHCi.
    
    4
    +Ok, one module loaded.
    
    5
    +Breakpoint 0 activated at T27287.hs:5:9-15
    
    6
    +Leaving GHCi.

  • testsuite/tests/ghci/should_run/all.T
    ... ... @@ -8,6 +8,7 @@ test('ghcirun002', just_ghci, compile_and_run, [''])
    8 8
     test('ghcirun003', just_ghci, compile_and_run, [''])
    
    9 9
     test('T2589',      just_ghci, compile_and_run, [''])
    
    10 10
     test('T2881',      just_ghci, compile_and_run, [''])
    
    11
    +test('T27287', [just_ghci, combined_output], makefile_test, [])
    
    11 12
     
    
    12 13
     test('T3171',
    
    13 14
          [when(opsys('mingw32'),skip),