[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Fixes for black holes
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: fde9cb2c by Luite Stegeman at 2026-05-28T05:42:39-04:00 Fixes for black holes - suspend duplicate work for eager black holes - detect eager black holes in checkBlockingQueues - don't overwrite existing black holes even if they're not in an eager blackhole frame - don't deadlock on self when thunk is already blackholed Fixes #26936 - - - - - f2725996 by Tom McLaughlin at 2026-05-28T05:42:51-04:00 Event/Windows.hsc: rethrow exceptions in overlapped IO This prevents the WinIO manager from swallowing exceptions in overlapped IO. It was added to make WinIO support possible in the `network` library. See https://gitlab.haskell.org/ghc/ghc/-/issues/27283. We also bump __IO_MANAGER_WINIO__ to 2 so libraries can gate on this using CPP. - - - - - 8b0a4bc5 by Wolfgang Jeltsch at 2026-05-28T05:42:52-04:00 Allow `downsweep` to use nodes of an existing module graph To this end, `downsweep` has not been able to use the nodes of a module graph obtained from a previous downsweeping round. In some GHC API applications, downsweeping is performed somewhat incrementally and therefore could profit from reusing such existing results. This contribution makes this possible. Resolves #27054. Co-authored-by: Matthew Pickering <matthewtpickering@gmail.com> - - - - - e9aef297 by Simon Jakobi at 2026-05-28T05:42:53-04:00 Add regression test for T11226 Closes #11226. - - - - - 28 changed files: - + changelog.d/fix-blackhole-handling - + changelog.d/module-graph-reuse-in-downsweep - + changelog.d/windows-rethrow-overlapped-exception - compiler/GHC/Driver/Downsweep.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/SysTools/Cpp.hs - libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc - rts/Messages.c - rts/ThreadPaused.c - rts/Threads.c - rts/Updates.h - rts/include/rts/storage/ClosureMacros.h - + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.hs - + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/A.hs - + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/B.hs - + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/C.hs - + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/D.hs - + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/X.hs - + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/Y.hs - + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/Z.hs - + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.stdout - testsuite/tests/ghc-api/downsweep/OldModLocation.hs - testsuite/tests/ghc-api/downsweep/PartialDownsweep.hs - testsuite/tests/ghc-api/downsweep/all.T - testsuite/tests/ghc-api/fixed-nodes/InterfaceModuleGraph.hs - + testsuite/tests/perf/should_run/T11226.hs - + testsuite/tests/perf/should_run/T11226.stdout - testsuite/tests/perf/should_run/all.T Changes: ===================================== changelog.d/fix-blackhole-handling ===================================== @@ -0,0 +1,6 @@ +section: rts +synopsis: Fix several black hole handling bugs that could lead to deadlocks + or crashes in multithreaded programs. These could show up as the program + hanging or "END_TSO_QUEUE object entered" errors. +issues: #26922 #26936 +mrs: !15640 ===================================== changelog.d/module-graph-reuse-in-downsweep ===================================== @@ -0,0 +1,9 @@ +section: compiler +synopsis: Allow `downsweep` to use nodes of an existing module graph +issues: #27054 +mrs: !16028 +description: { + This contribution enables `downsweep` to use the nodes of a module + graph obtained from a previous downsweeping round, which allows GHC + API applications to build module graphs somewhat incrementally. +} ===================================== changelog.d/windows-rethrow-overlapped-exception ===================================== @@ -0,0 +1,8 @@ +section: rts +synopsis: Rethrow exceptions in overlapped IO when using the WinIO IO manager. +issues: #27283 +mrs: !15887 + +description: { + This change was made to support WinIO in the network library; see https://github.com/haskell/network/issues/602. +} ===================================== compiler/GHC/Driver/Downsweep.hs ===================================== @@ -146,6 +146,10 @@ The result is having a uniform graph available for the whole compilation pipelin -- an import of this module mean. type DownsweepCache = M.Map (UnitId, PkgQual, ModuleNameWithIsBoot) [Either DriverMessages ModuleNodeInfo] +moduleGraphNodeMap :: ModuleGraph -> M.Map NodeKey ModuleGraphNode +moduleGraphNodeMap graph + = M.fromList [(mkNodeKey node, node) | node <- mgModSummaries' graph] + ----------------------------------------------------------------------------- -- -- | Downsweep (dependency analysis) for --make mode @@ -158,6 +162,13 @@ type DownsweepCache = M.Map (UnitId, PkgQual, ModuleNameWithIsBoot) [Either Driv -- cache to avoid recalculating a module summary if the source is -- unchanged. -- +-- Downsweeping can start from scratch for from a given module graph. In the +-- latter case, the given graph is fully included in the resulting graph, even +-- if parts of it are not reachable from any of the given roots. When an import +-- is processed, the source of the imported module is not consulted if this +-- module is already mentioned in the given graph. The sources of the root +-- modules are always consulted, though. +-- -- The returned ModuleGraph has one node for each home-package -- module, plus one for any hs-boot files. The imports of these nodes -- are all there, including the imports of non-home-package modules. @@ -172,6 +183,8 @@ downsweep :: HscEnv -> Maybe Messager -> [ModSummary] -- ^ Old summaries + -> Maybe ModuleGraph + -- ^ Optionally a module graph to extend -> [ModuleName] -- Ignore dependencies on these; treat -- them as if they were package modules -> Bool -- True <=> allow multiple targets to have @@ -181,7 +194,7 @@ downsweep :: HscEnv -- The non-error elements of the returned list all have distinct -- (Modules, IsBoot) identifiers, unless the Bool is true in -- which case there can be repeats -downsweep hsc_env diag_wrapper msg old_summaries excl_mods allow_dup_roots = do +downsweep hsc_env diag_wrapper msg old_summaries maybe_base_graph excl_mods allow_dup_roots = do n_jobs <- mkWorkerLimit (hsc_dflags hsc_env) (root_errs, root_summaries) <- rootSummariesParallel n_jobs hsc_env diag_wrapper msg summary let closure_errs = checkHomeUnitsClosed unit_env @@ -191,7 +204,7 @@ downsweep hsc_env diag_wrapper msg old_summaries excl_mods allow_dup_roots = do case all_errs of [] -> do - (downsweep_errs, downsweep_nodes) <- downsweepFromRootNodes hsc_env old_summary_map excl_mods allow_dup_roots DownsweepUseCompile (map ModuleNodeCompile root_summaries) [] + (downsweep_errs, downsweep_nodes) <- downsweepFromRootNodes hsc_env old_summary_map maybe_base_graph excl_mods allow_dup_roots DownsweepUseCompile (map ModuleNodeCompile root_summaries) [] let (other_errs, unit_nodes) = partitionEithers $ HUG.unitEnv_foldWithKey (\nodes uid hue -> nodes ++ unitModuleNodes downsweep_nodes uid hue) [] (hsc_HUG hsc_env) @@ -232,7 +245,7 @@ downsweep hsc_env diag_wrapper msg old_summaries excl_mods allow_dup_roots = do downsweepThunk :: HscEnv -> ModSummary -> IO ModuleGraph downsweepThunk hsc_env mod_summary = unsafeInterleaveIO $ do debugTraceMsg (hsc_logger hsc_env) 3 $ text "Computing Module Graph thunk..." - ~(errs, mg) <- downsweepFromRootNodes hsc_env mempty [] True DownsweepUseFixed [ModuleNodeCompile mod_summary] [] + ~(errs, mg) <- downsweepFromRootNodes hsc_env mempty Nothing [] True DownsweepUseFixed [ModuleNodeCompile mod_summary] [] let dflags = hsc_dflags hsc_env liftIO $ printOrThrowDiagnostics (hsc_logger hsc_env) (initPrintConfig dflags) @@ -360,7 +373,7 @@ downsweepInstalledModules hsc_env mods = do _ -> throwGhcException $ ProgramError $ showSDoc (hsc_dflags hsc_env) $ text "downsweepInstalledModules: Could not find installed module" <+> ppr i nodes <- mapM process installed_mods - (errs, mg) <- downsweepFromRootNodes hsc_env mempty [] True DownsweepUseFixed nodes external_uids + (errs, mg) <- downsweepFromRootNodes hsc_env mempty Nothing [] True DownsweepUseFixed nodes external_uids -- Similarly here, we should really not get any errors, but print them out if we do. let dflags = hsc_dflags hsc_env @@ -385,19 +398,21 @@ data DownsweepMode = DownsweepUseCompile | DownsweepUseFixed -- all the dependencies, all the way to the leaf units. downsweepFromRootNodes :: HscEnv -> M.Map (UnitId, OsPath) ModSummary + -> Maybe ModuleGraph -> [ModuleName] -> Bool -> DownsweepMode -- ^ Whether to create fixed or compile nodes for dependencies -> [ModuleNodeInfo] -- ^ The starting ModuleNodeInfo -> [UnitId] -- ^ The starting units -> IO ([DriverMessages], [ModuleGraphNode]) -downsweepFromRootNodes hsc_env old_summaries excl_mods allow_dup_roots mode root_nodes root_uids +downsweepFromRootNodes hsc_env old_summaries maybe_base_graph excl_mods allow_dup_roots mode root_nodes root_uids = do let root_map = mkRootMap root_nodes checkDuplicates root_map let env = DownsweepEnv hsc_env mode old_summaries excl_mods (deps', map0) <- runDownsweepM env $ do - (module_deps, map0) <- loopModuleNodeInfos root_nodes (M.empty, root_map) + let base_nodes = maybe M.empty moduleGraphNodeMap maybe_base_graph + (module_deps, map0) <- loopModuleNodeInfos root_nodes (base_nodes, root_map) let all_deps = loopUnit hsc_env module_deps root_uids let all_instantiations = getHomeUnitInstantiations hsc_env deps' <- loopInstantiations all_instantiations all_deps ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -232,7 +232,7 @@ depanalPartial diag_wrapper msg excluded_mods allow_dup_roots = do liftIO $ flushFinderCaches (hsc_FC hsc_env) (hsc_unit_env hsc_env) (errs, mod_graph) <- liftIO $ downsweep - hsc_env diag_wrapper msg (mgModSummaries old_graph) + hsc_env diag_wrapper msg (mgModSummaries old_graph) Nothing excluded_mods allow_dup_roots return (unionManyMessages errs, mod_graph) ===================================== compiler/GHC/SysTools/Cpp.hs ===================================== @@ -148,7 +148,7 @@ doCpp logger tmpfs dflags unit_env opts input_fn output_fn = do -- and BUILD is the same as our HOST. let io_manager_defs = - [ "-D__IO_MANAGER_WINIO__=1" | isWindows ] ++ + [ "-D__IO_MANAGER_WINIO__=2" | isWindows ] ++ [ "-D__IO_MANAGER_MIO__=1" ] let sse_defs = ===================================== libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc ===================================== @@ -690,7 +690,11 @@ withOverlappedEx mgr fname h async offset startCB completionCB = do -- can go into an unbounded alertable wait. delay <- runExpiredTimeouts mgr registerAlertableWait delay - return $ IOFailed Nothing + -- Re-throw the original exception rather than + -- returning IOFailed. This ensures that async + -- exceptions (e.g. Timeout from System.Timeout) + -- propagate correctly to their handlers. + E.throw e let runner = do debugIO $ (dbgMsg ":: waiting ") ++ " | " ++ show lpol res <- readMVar signal `catch` cancel debugIO $ dbgMsg ":: signaled " ===================================== rts/Messages.c ===================================== @@ -188,10 +188,7 @@ uint32_t messageBlackHole(Capability *cap, MessageBlackHole *msg) // BLACKHOLE has already been updated, and GC has shorted out the // indirection, so the pointer no longer points to a BLACKHOLE at // all. - if (bh_info != &stg_BLACKHOLE_info && - bh_info != &stg_CAF_BLACKHOLE_info && - bh_info != &__stg_EAGER_BLACKHOLE_info && - bh_info != &stg_WHITEHOLE_info) { + if (!IS_BLACKHOLE_OR_WHITEHOLE_INFO(bh_info)) { return 0; } @@ -350,10 +347,7 @@ StgTSO * blackHoleOwner (StgClosure *bh) info = RELAXED_LOAD(&bh->header.info); - if (info != &stg_BLACKHOLE_info && - info != &stg_CAF_BLACKHOLE_info && - info != &__stg_EAGER_BLACKHOLE_info && - info != &stg_WHITEHOLE_info) { + if (!IS_BLACKHOLE_OR_WHITEHOLE_INFO(info)) { return NULL; } ===================================== rts/ThreadPaused.c ===================================== @@ -183,6 +183,30 @@ stackSqueeze(Capability *cap, StgTSO *tso, StgPtr bottom) } } +/* + * Check whether tso is the owner of the black hole bh. + * + * We must call this from the capability that runs tso, + * since that guarantees that the writes to bh->indirectee + * by tso claiming ownership have been visible. If another + * tso has claimed it again afterwards we can safely suspend + * our work. + */ +static bool +threadPausedBlackHoleOwner(StgTSO *tso, StgClosure *bh) +{ + StgClosure *ind = RELAXED_LOAD(&((StgInd*)bh)->indirectee); + if (ind == (StgClosure*)tso) { + return true; + } + const StgInfoTable *ind_info = GET_INFO(UNTAG_CLOSURE(ind)); + if (ind_info == &stg_BLOCKING_QUEUE_CLEAN_info + || ind_info == &stg_BLOCKING_QUEUE_DIRTY_info) { + return ((StgBlockingQueue*)UNTAG_CLOSURE(ind))->owner == tso; + } + return false; +} + /* ----------------------------------------------------------------------------- * Pausing a thread * @@ -255,11 +279,10 @@ threadPaused(Capability *cap, StgTSO *tso) // Note [suspend duplicate work] // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // If the info table is a WHITEHOLE or a BLACKHOLE, then - // another thread has claimed it (via the SET_INFO() - // below), or is in the process of doing so. In that case - // we want to suspend the work that the current thread has - // done on this thunk and wait until the other thread has - // finished. + // some thread has claimed it, or is in the process of doing + // so. In that case we want to suspend the work that the + // current thread has done on this thunk and wait until the + // other thread has finished. // // If eager blackholing is taking place, it could be the // case that the blackhole points to the current @@ -287,8 +310,8 @@ threadPaused(Capability *cap, StgTSO *tso) // Note that great care is required when entering computations // suspended by this mechanism. See Note [AP_STACKs must be eagerly // blackholed] for details. - if (((bh_info == &stg_BLACKHOLE_info) - && (RELAXED_LOAD(&((StgInd*)bh)->indirectee) != (StgClosure*)tso)) + if ((IS_BLACKHOLE_INFO(bh_info) + && !threadPausedBlackHoleOwner(tso, bh)) || (bh_info == &stg_WHITEHOLE_info)) { debugTrace(DEBUG_squeeze, @@ -318,14 +341,13 @@ threadPaused(Capability *cap, StgTSO *tso) // If we have a frame that is already eagerly blackholed, we // shouldn't overwrite its payload: There may already be a blocking // queue (see #26324). - if(frame_info == &stg_bh_upd_frame_info) { - // eager black hole: we do nothing + if(frame_info == &stg_bh_upd_frame_info + || IS_BLACKHOLE_INFO(bh_info)) { + // already a black hole: we do nothing // it should be a black hole (but we may not own it, as another // thread could have raced us to claim it) - ASSERT(bh_info == &stg_BLACKHOLE_info || - bh_info == &__stg_EAGER_BLACKHOLE_info || - bh_info == &stg_CAF_BLACKHOLE_info); + ASSERT(IS_BLACKHOLE_INFO(bh_info)); } else { // lazy black hole ===================================== rts/Threads.c ===================================== @@ -474,7 +474,7 @@ checkBlockingQueues (Capability *cap, StgTSO *tso) // thing the result would be the same in almost all cases. See #20093. p = UNTAG_CLOSURE(bq->bh); const StgInfoTable *pinfo = ACQUIRE_LOAD(&p->header.info); - if (pinfo != &stg_BLACKHOLE_info || + if (!IS_BLACKHOLE_INFO(pinfo) || (RELAXED_LOAD(&((StgInd *)p)->indirectee) != (StgClosure*)bq)) { wakeBlockingQueue(cap,bq); @@ -498,10 +498,7 @@ updateThunk (Capability *cap, StgTSO *tso, StgClosure *thunk, StgClosure *val) const StgInfoTable *i; i = ACQUIRE_LOAD(&thunk->header.info); - if (i != &stg_BLACKHOLE_info && - i != &stg_CAF_BLACKHOLE_info && - i != &__stg_EAGER_BLACKHOLE_info && - i != &stg_WHITEHOLE_info) { + if (!IS_BLACKHOLE_OR_WHITEHOLE_INFO(i)) { updateWithIndirection(cap, thunk, val); return; } ===================================== rts/Updates.h ===================================== @@ -190,9 +190,9 @@ * frame is encountered, it checks the info table of the updatee and: * * - if it is `BLACKHOLE`, then the thunk has already been claimed for evaluation - * by another thread, and the yielding thread is instead added to the - * `BLACKHOLE`'s blocking queue (see Note [suspend duplicate work] in - * `ThreadPaused.c`). + * by some thread. If that's not the yielding thread itself, the yielding thread + * is added to the `BLACKHOLE`'s blocking queue (see Note [suspend duplicate + * work] in `ThreadPaused.c`). * * - if not, then it blackholes the thunk as done in eager blackholing (but * using the `BLACKHOLE_info` info table instead of `EAGER_BLACKHOLE_info`). ===================================== rts/include/rts/storage/ClosureMacros.h ===================================== @@ -382,6 +382,18 @@ EXTERN_INLINE StgOffset BLACKHOLE_sizeW ( void ); EXTERN_INLINE StgOffset BLACKHOLE_sizeW ( void ) { return sizeofW(StgInd); } // a BLACKHOLE is a kind of indirection +/* ----------------------------------------------------------------------------- + Blackhole predicates + -------------------------------------------------------------------------- */ + +#define IS_BLACKHOLE_INFO(info) \ + ((info) == &stg_BLACKHOLE_info || \ + (info) == &__stg_EAGER_BLACKHOLE_info || \ + (info) == &stg_CAF_BLACKHOLE_info) + +#define IS_BLACKHOLE_OR_WHITEHOLE_INFO(info) \ + (IS_BLACKHOLE_INFO(info) || (info) == &stg_WHITEHOLE_info) + /* -------------------------------------------------------------------------- Sizes of closures ------------------------------------------------------------------------*/ ===================================== testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.hs ===================================== @@ -0,0 +1,105 @@ +{-# LANGUAGE Haskell2010 #-} + +{-# OPTIONS_GHC -Wall -Werror #-} + +import Control.Monad (unless) +import Control.Monad.IO.Class (liftIO) +import Control.Arrow ((>>>)) +import Data.List (sort) +import System.Environment (getArgs) +import System.Exit (exitFailure) +import System.IO (stderr) +import System.Directory (removeFile) +import Language.Haskell.Syntax.Module.Name (moduleNameString) +import GHC.Utils.Ppr (Mode (PageMode)) +import GHC.Utils.Outputable (vcat, defaultSDocContext, printSDocLn, ppr) +import GHC.Utils.Logger (getLogger) +import GHC.Types.SrcLoc (noLoc) +import GHC.Types.Error (mkUnknownDiagnostic) +import GHC.Unit.Types (moduleName) +import GHC.Unit.Module.ModSummary (ms_mod) +import GHC.Unit.Module.Graph (ModuleGraph, mgModSummaries) +import GHC.Driver.DynFlags (defaultFatalMessager, defaultFlushOut) +import GHC.Driver.Monad (Ghc, getSession, getSessionDynFlags) +import GHC.Driver.Make (downsweep) +import GHC.Driver.Errors.Types (DriverMessages) +import GHC + ( + defaultErrorHandler, + guessTarget, + setTargets, + parseDynamicFlags, + setSessionDynFlags, + runGhc + ) + +sourceDirectory :: String +sourceDirectory = "IncrementalDownsweep.modules" + +withSimpleErrorHandler :: Ghc a -> Ghc a +withSimpleErrorHandler = defaultErrorHandler defaultFatalMessager + defaultFlushOut + +handleDriverMessages :: [DriverMessages] -> IO () +handleDriverMessages driverMsgs + = unless (null driverMsgs) $ + do + printSDocLn defaultSDocContext + (PageMode True) + stderr + (vcat (map ppr driverMsgs)) + exitFailure + +performDownsweepTurn :: Maybe ModuleGraph -> String -> Ghc ModuleGraph +performDownsweepTurn maybeGivenModuleGraph rootModuleName = do + target <- guessTarget rootModuleName Nothing Nothing + setTargets [target] + session <- getSession + (driverMsgs, resultingModuleGraph) + <- liftIO $ downsweep session + mkUnknownDiagnostic + Nothing + [] + maybeGivenModuleGraph + [] + False + liftIO $ handleDriverMessages driverMsgs + return resultingModuleGraph + +outputModuleNamesInGraph :: ModuleGraph -> IO () +outputModuleNamesInGraph = mgModSummaries >>> + map (ms_mod >>> moduleName >>> moduleNameString) >>> + sort >>> + print + +main :: IO () +main = do + libDir : otherArgs <- getArgs + runGhc (Just libDir) $ withSimpleErrorHandler $ do + + -- Setup + logger <- getLogger + originalDynFlags <- getSessionDynFlags + (finalDynFlags, _, _) + <- parseDynamicFlags logger originalDynFlags $ + map noLoc (["-i", "-i" ++ sourceDirectory] ++ otherArgs) + _ <- setSessionDynFlags finalDynFlags + + -- Turn 1: From scratch, using 'A' as root + moduleGraph1 <- performDownsweepTurn Nothing "A" + liftIO $ outputModuleNamesInGraph moduleGraph1 + + -- Turn 2: From scratch, using 'X' as root + -- NOTE: 'A' is not included, because it is not reachable. + moduleGraph2 <- performDownsweepTurn Nothing "X" + liftIO $ outputModuleNamesInGraph moduleGraph2 + + -- Deletion of the source files used in turn 1 + _ <- liftIO $ + mapM_ (((sourceDirectory ++ "/") ++) >>> (++ ".hs") >>> removeFile) + ["A", "B", "C", "D"] + + -- Turn 3: Based on the result of turn 1, using 'X' as root + -- NOTE: 'A' is included, because the result of turn 1 contains it. + moduleGraph3 <- performDownsweepTurn (Just moduleGraph1) "X" + liftIO $ outputModuleNamesInGraph moduleGraph3 ===================================== testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/A.hs ===================================== @@ -0,0 +1,4 @@ +module A where + +import B +import C ===================================== testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/B.hs ===================================== @@ -0,0 +1,3 @@ +module B where + +import D ===================================== testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/C.hs ===================================== @@ -0,0 +1,3 @@ +module C where + +import D ===================================== testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/D.hs ===================================== @@ -0,0 +1 @@ +module D where ===================================== testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/X.hs ===================================== @@ -0,0 +1,4 @@ +module X where + +import Y +import Z ===================================== testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/Y.hs ===================================== @@ -0,0 +1,3 @@ +module Y where + +import B ===================================== testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/Z.hs ===================================== @@ -0,0 +1,3 @@ +module Z where + +import C ===================================== testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.stdout ===================================== @@ -0,0 +1,3 @@ +["A","B","C","D"] +["B","C","D","X","Y","Z"] +["A","B","C","D","X","Y","Z"] ===================================== testsuite/tests/ghc-api/downsweep/OldModLocation.hs ===================================== @@ -48,13 +48,13 @@ main = do liftIO $ do - _emss <- downsweep hsc_env mkUnknownDiagnostic Nothing [] [] False + _emss <- downsweep hsc_env mkUnknownDiagnostic Nothing [] Nothing [] False flushFinderCaches (hsc_FC hsc_env) (hsc_unit_env hsc_env) createDirectoryIfMissing False "mydir" renameFile "B.hs" "mydir/B.hs" - (_, nodes) <- downsweep hsc_env mkUnknownDiagnostic Nothing [] [] False + (_, nodes) <- downsweep hsc_env mkUnknownDiagnostic Nothing [] Nothing [] False -- If 'checkSummaryTimestamp' were to call 'addHomeModuleToFinder' with -- (ms_location old_summary) like summariseFile used to instead of ===================================== testsuite/tests/ghc-api/downsweep/PartialDownsweep.hs ===================================== @@ -169,7 +169,7 @@ go label mods cnd = setTargets [tgt] hsc_env <- getSession - (_, nodes) <- liftIO $ downsweep hsc_env mkUnknownDiagnostic Nothing [] [] False + (_, nodes) <- liftIO $ downsweep hsc_env mkUnknownDiagnostic Nothing [] Nothing [] False it label $ cnd (mgModSummaries nodes) ===================================== testsuite/tests/ghc-api/downsweep/all.T ===================================== @@ -14,3 +14,10 @@ test('OldModLocation', ], compile_and_run, ['-package ghc']) + +test('IncrementalDownsweep', + [ extra_files(['IncrementalDownsweep.modules/']) + , extra_run_opts('"' + config.libdir + '"') + ], + compile_and_run, + ['-package ghc']) ===================================== testsuite/tests/ghc-api/fixed-nodes/InterfaceModuleGraph.hs ===================================== @@ -67,7 +67,7 @@ main = do keyC = msKey msC let mkGraph s = do - ([], nodes) <- downsweepFromRootNodes hsc_env mempty [] True DownsweepUseFixed s [] + ([], nodes) <- downsweepFromRootNodes hsc_env mempty Nothing [] True DownsweepUseFixed s [] return $ mkModuleGraph nodes graph <- liftIO $ mkGraph [ModuleNodeCompile msC] ===================================== testsuite/tests/perf/should_run/T11226.hs ===================================== @@ -0,0 +1,10 @@ +module Main where + +main :: IO () +main = print $ sum $ map bitcount [0, 4 .. 2 ^ (24 :: Int) - 1] + +bitcount :: Int -> Int +bitcount x = + if x > 0 + then let (d, m) = divMod x 2 in bitcount d + m + else 0 ===================================== testsuite/tests/perf/should_run/T11226.stdout ===================================== @@ -0,0 +1 @@ +46137344 ===================================== testsuite/tests/perf/should_run/all.T ===================================== @@ -30,6 +30,13 @@ test('T10359', compile_and_run, ['-O']) +test('T11226', + [collect_runtime_residency(10), + only_ways(['normal']) + ], + compile_and_run, + ['-O2']) + test('T14955', [collect_stats('bytes allocated',5), only_ways(['normal']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/179e22a998c7783116cc7bf92a3611e... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/179e22a998c7783116cc7bf92a3611e... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Marge Bot (@marge-bot)